From 4c16542181bb1140c0784842a9918c23aa256df0 Mon Sep 17 00:00:00 2001 From: xiaying Date: Thu, 4 Jul 2024 11:53:45 +0800 Subject: [PATCH] MNN:Sync: Sync Internal 2.9.2 --- CMakeLists.txt | 13 +- docs/Makefile | 20 - docs/inference/module.md | 2 +- docs/tools/convert.md | 2 +- docs/transformers/diffusion.md | 44 +- include/MNN/MNNDefine.h | 2 +- project/android/updateTest.sh | 1 + pymnn/examples/MNNLlm/llm_example.py | 19 + pymnn/pip_package/MNN/llm/__init__.py | 76 + pymnn/pip_package/build_deps.py | 12 + pymnn/pip_package/setup.py | 9 + pymnn/src/MNN.cc | 22 +- pymnn/src/llm.h | 113 + pymnn/src/util.h | 10 +- pymnn/test/README.md | 4 +- source/backend/cpu/CPUAttention.cpp | 102 +- source/backend/cpu/CPUAttention.hpp | 5 +- source/backend/cpu/CPUBackend.cpp | 6 +- source/backend/cpu/CPUUnary.cpp | 1 + source/backend/metal/AllShader.cpp | 229 - source/backend/metal/AllShader.hpp | 1 - source/backend/metal/MetalBackend.hpp | 5 +- source/backend/metal/MetalBackend.mm | 576 +- source/backend/metal/ShaderMap.cpp | 1 - .../backend/metal/shader/MetalBackend.metal | 235 - .../backend/opencl/core/BufferConvertor.cpp | 4 +- source/backend/opencl/core/OpenCLGemmTune.cpp | 417 + .../backend/opencl/core/OpenCLOPRegister.cpp | 6 + .../opencl/core/OpenCLRunningUtils.cpp | 62 +- .../opencl/core/OpenCLRunningUtils.hpp | 3 +- .../opencl/core/runtime/OpenCLRuntime.cpp | 97 +- .../opencl/core/runtime/OpenCLRuntime.hpp | 8 +- .../buffer/AttentionBufExecution.cpp | 70 +- .../buffer/AttentionBufExecution.hpp | 9 +- .../execution/buffer/BinaryBufExecution.cpp | 2 +- .../execution/buffer/ConvBufExecution.cpp | 244 +- .../execution/buffer/ConvBufExecution.hpp | 6 +- .../buffer/ConvBufLowMemoryExecution.cpp | 427 +- .../buffer/ConvBufLowMemoryExecution.hpp | 6 +- .../execution/buffer/ConvBufWinograd.cpp | 284 +- .../execution/buffer/ConvBufWinograd.hpp | 5 + .../buffer/DepthwiseConvBufExecution.cpp | 5 +- .../buffer/GroupNormBufExecution.cpp | 267 + .../buffer/GroupNormBufExecution.hpp | 45 + .../execution/buffer/LoopBufExecution.cpp | 166 +- .../buffer/SelfAttentionBufExecution.cpp | 586 + .../buffer/SelfAttentionBufExecution.hpp | 79 + .../buffer/SplitGeluBufExecution.cpp | 103 + .../buffer/SplitGeluBufExecution.hpp | 39 + .../backend/opencl/execution/cl/argmax_buf.cl | 4 +- .../opencl/execution/cl/attention_buf.cl | 232 +- .../opencl/execution/cl/buffer_convert_buf.cl | 121 - .../execution/cl/buffer_convert_quant.cl | 242 + source/backend/opencl/execution/cl/conv_2d.cl | 288 +- .../opencl/execution/cl/conv_2d_int_buf.cl | 465 +- source/backend/opencl/execution/cl/gemm.cl | 100 +- .../execution/cl/gemm_quant_batch_buf.cl | 780 + .../opencl/execution/cl/gemv_conv1x1_buf.cl | 2239 +- .../opencl/execution/cl/groupnorm_buf.cl | 243 + .../opencl/execution/cl/layernorm_buf.cl | 20 +- .../backend/opencl/execution/cl/loop_buf.cl | 132 +- .../opencl/execution/cl/matmul_params_buf.cl | 743 +- .../opencl/execution/cl/opencl_codegen.py | 124 +- .../opencl/execution/cl/opencl_program.cc | 22863 +++++++++++++++- .../opencl/execution/cl/opencl_source_map.hpp | 341 + .../opencl/execution/cl/self_attention_buf.cl | 364 + .../opencl/execution/cl/splitgelu_buf.cl | 60 + .../execution/cl/winogradTransform_buf.cl | 262 +- .../opencl/execution/image/ConvExecution.cpp | 24 +- .../opencl/execution/image/ConvExecution.hpp | 4 +- .../image/ConvLowMemoryExecution.cpp | 152 +- .../execution/image/RasterExecution.cpp | 12 +- source/backend/opencl/schema/CLCache.fbs | 6 + .../opencl/schema/current/CLCache_generated.h | 144 +- source/core/Pipeline.cpp | 10 +- source/core/Tensor.cpp | 2 +- test/MNNTestSuite.cpp | 12 +- test/core/BackendTest.cpp | 2 +- tools/converter/source/onnx/IdentityOnnx.cpp | 18 + .../source/optimizer/merge/FuseFmhaV2.cpp | 247 + .../source/optimizer/merge/FuseGroupNorm.cpp | 44 +- .../source/optimizer/merge/FuseSplitGeLu.cpp | 37 +- .../onnxextra/ResolveIdentityOnnx.cpp | 56 - .../postconvert/MergeBNToConvolution.cpp | 19 +- .../postconvert/MergeScaleToConvolution.cpp | 20 +- .../postconvert/MergeToConvolution.hpp | 8 + .../postconvert/TransformGroupConvolution.cpp | 19 +- tools/cpp/ExprDebug.hpp | 4 +- tools/cpp/testModel.cpp | 1 + tools/cv/source/imgcodecs/imgcodecs.cpp | 2 +- tools/quantization/Helper.cpp | 47 +- tools/quantization/TensorStatistic.cpp | 74 +- tools/quantization/calibration.cpp | 1043 +- tools/quantization/calibration.hpp | 17 +- transformers/diffusion/README.md | 45 + transformers/diffusion/export/onnx_export.py | 212 + transformers/diffusion/main.cpp | 17 +- transformers/diffusion/pipeline.cpp | 117 +- transformers/diffusion/pipeline.hpp | 11 +- transformers/diffusion/scheduler/alphas.txt | 1000 + transformers/diffusion/tokenizer.cpp | 2 +- transformers/llm/engine/CMakeLists.txt | 18 +- transformers/llm/engine/include/llm.hpp | 61 +- transformers/llm/engine/include/tokenizer.hpp | 56 +- transformers/llm/engine/llm_demo.cpp | 1 + transformers/llm/engine/src/llm.cpp | 85 +- transformers/llm/engine/src/tokenizer.cpp | 30 +- transformers/llm/eval/evaluate_chat_ceval.py | 508 + 108 files changed, 33412 insertions(+), 4848 deletions(-) delete mode 100644 docs/Makefile create mode 100644 pymnn/examples/MNNLlm/llm_example.py create mode 100644 pymnn/pip_package/MNN/llm/__init__.py create mode 100644 pymnn/src/llm.h delete mode 100644 source/backend/metal/shader/MetalBackend.metal create mode 100644 source/backend/opencl/core/OpenCLGemmTune.cpp create mode 100644 source/backend/opencl/execution/buffer/GroupNormBufExecution.cpp create mode 100644 source/backend/opencl/execution/buffer/GroupNormBufExecution.hpp create mode 100644 source/backend/opencl/execution/buffer/SelfAttentionBufExecution.cpp create mode 100644 source/backend/opencl/execution/buffer/SelfAttentionBufExecution.hpp create mode 100644 source/backend/opencl/execution/buffer/SplitGeluBufExecution.cpp create mode 100644 source/backend/opencl/execution/buffer/SplitGeluBufExecution.hpp create mode 100644 source/backend/opencl/execution/cl/buffer_convert_quant.cl create mode 100644 source/backend/opencl/execution/cl/gemm_quant_batch_buf.cl create mode 100644 source/backend/opencl/execution/cl/groupnorm_buf.cl create mode 100644 source/backend/opencl/execution/cl/opencl_source_map.hpp create mode 100644 source/backend/opencl/execution/cl/self_attention_buf.cl create mode 100644 source/backend/opencl/execution/cl/splitgelu_buf.cl delete mode 100644 tools/converter/source/optimizer/onnxextra/ResolveIdentityOnnx.cpp create mode 100644 transformers/diffusion/README.md create mode 100644 transformers/diffusion/export/onnx_export.py create mode 100755 transformers/diffusion/scheduler/alphas.txt create mode 100644 transformers/llm/eval/evaluate_chat_ceval.py diff --git a/CMakeLists.txt b/CMakeLists.txt index bd2220bc7..abb66d6c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -636,11 +636,6 @@ IF(MNN_BUILD_CODEGEN) include(${CMAKE_CURRENT_LIST_DIR}/codegen/CMakeLists.txt) ENDIF() -IF(MNN_BUILD_LLM) - # add_definitions(-DMNN_BUILD_LLM) - include(${CMAKE_CURRENT_LIST_DIR}/transformers/llm/engine/CMakeLists.txt) -ENDIF() - # NPU IF(MNN_NPU) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/source/backend/hiai/) @@ -735,6 +730,14 @@ IF(MNN_BUILD_OPENCV AND NOT MNN_SEP_BUILD) target_sources(MNN PRIVATE $) ENDIF() +IF(MNN_BUILD_LLM) + # add_definitions(-DMNN_BUILD_LLM) + include(${CMAKE_CURRENT_LIST_DIR}/transformers/llm/engine/CMakeLists.txt) + IF(NOT MNN_SEP_BUILD) + target_sources(MNN PRIVATE $) + ENDIF() +ENDIF() + if(CMAKE_SYSTEM_NAME MATCHES "^Linux") # Using -pthread, needed by thread-safe implemention of glibc, is better than only using -lpthread # https://stackoverflow.com/questions/23250863/difference-between-pthread-and-lpthread-while-compiling diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d4bb2cbb9..000000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/inference/module.md b/docs/inference/module.md index d1bbd58e7..22347a576 100644 --- a/docs/inference/module.md +++ b/docs/inference/module.md @@ -225,7 +225,7 @@ MNN::TensorCallBackWithInfo callBack = [&](const std::vector& nten return true; }; -// 设置回调函数,需要是创建该 Module 时的 executor ,非多实例情况下用全局 executor 即可: +// 设置回调函数,需要时创建该 Module 时的 executor ,非多实例情况下用全局 executor 即可: Express::Executor::getGlobalExecutor()->setCallBack(std::move(beforeCallBack), std::move(callBack)); // forward would trigger callback diff --git a/docs/tools/convert.md b/docs/tools/convert.md index 98b1aac98..f8ab79101 100644 --- a/docs/tools/convert.md +++ b/docs/tools/convert.md @@ -48,7 +48,7 @@ Usage: --weightQuantAsymmetric 与weightQuantBits结合使用,决定是否用非对称量化,默认为`true` --compressionParamsFile arg - 使用MNN模型压缩工具箱生成的模型压缩信息文件 + 使用MNN模型压缩工具箱生成的模型压缩信息文件或根据用户提供的量化参数来生成对应的量化模型,量化参数文件可参考tools/converter/user_provide_quant_params.json --saveStaticModel 固定输入形状,保存静态模型, default: false diff --git a/docs/transformers/diffusion.md b/docs/transformers/diffusion.md index da22cb304..ffe6eb9d0 100644 --- a/docs/transformers/diffusion.md +++ b/docs/transformers/diffusion.md @@ -1,3 +1,45 @@ # 扩散模型 -TODO \ No newline at end of file +## 模型支持与下载 + +[Download-runwayml/stable-diffusion-v1-5]: +https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main +[Download-IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1]: +https://huggingface.co/IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1/tree/main + +## 模型转换 +### 将Huggingface的Stable Diffusion模型 转为onnx模型 +python export/onnx_export.py \ + --model_path hf_sd_load_path \ + --output_path onnx_save_path + +### 将onnx模型转为mnn模型 +新建diffusion mnn模型文件夹,将转好的mnn文件放在该文件夹下。 +./MNNConvert -f ONNX --modelFile onnx_save_path/text_encoder/model.onnx --MNNModel mnn_save_path/text_encoder.mnn --weightQuantBits 8 --bizCode biz +./MNNConvert -f ONNX --modelFile onnx_save_path/unet/model.onnx --MNNModel mnn_save_path/unet.mnn --transformerFuse --weightQuantBits 8 --bizCode biz +./MNNConvert -f ONNX --modelFile onnx_save_path/vae_decoder/model.onnx --keepInputFormat --MNNModel mnn_save_path/vae_decoder.mnn --weightQuantBits 8 --bizCode biz + +## 编译Diffusion Demo +### Linux/MAC/Windows上 +cmake .. -DMNN_BUILD_DIFFUSION=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_OPENCL=ON -DMNN_SEP_BUILD=OFF -DMNN_SUPPORT_TRANSFORMER_FUSE=ON + +### Android上 +cd project/android/build +../build_64.sh -DMNN_BUILD_DIFFUSION=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_OPENCL=ON -DMNN_SEP_BUILD=OFF -DMNN_SUPPORT_TRANSFORMER_FUSE=ON + +## 运行Diffusion Demo +./diffusion_demo +其中,resource_path 就是mnn模型文件的路径,除了mnn文件,还需要 +(1)将MNN目录transformers/diffusion/scheduler/alphas.txt文件拷贝到该文件夹下。 +(2)针对stable-diffusion-v1-5模型需要将huggingfacetokenizer目录下merges.txt和vocab.json拷贝到该文件夹中。针对Taiyi-Stable-Diffusion模型需要将huggingfacetokenizer目录下vocab.txt拷贝到该文件夹中。 + +model_type是目前支持的两种diffusion模型的类别。如果是stable-diffusion-v1-5模型设为0,如果是Taiyi-Stable-Diffusion模型设为1。 + +output_image_name是生成图片的名字,默认图片位置在当前运行目录下。 + +input_text是文生图的prompt,如果是stable-diffusion-v1-5模型建议英文prompt,如果是Taiyi-Stable-Diffusion建议中文prompt。 + +运行指令例如: +./diffusion_demo mnn_save_path 0 demo.jpg "a cute cat" +./diffusion_demo mnn_save_path 1 demo.jpg "一只可爱的猫" + diff --git a/include/MNN/MNNDefine.h b/include/MNN/MNNDefine.h index dc81a3872..b6d6645db 100644 --- a/include/MNN/MNNDefine.h +++ b/include/MNN/MNNDefine.h @@ -69,6 +69,6 @@ MNN_ERROR("Check failed: %s ==> %s\n", #success, #log); \ #define STR(x) STR_IMP(x) #define MNN_VERSION_MAJOR 2 #define MNN_VERSION_MINOR 9 -#define MNN_VERSION_PATCH 1 +#define MNN_VERSION_PATCH 2 #define MNN_VERSION STR(MNN_VERSION_MAJOR) "." STR(MNN_VERSION_MINOR) "." STR(MNN_VERSION_PATCH) #endif /* MNNDefine_h */ diff --git a/project/android/updateTest.sh b/project/android/updateTest.sh index 7d682bd5a..29c13242c 100755 --- a/project/android/updateTest.sh +++ b/project/android/updateTest.sh @@ -4,6 +4,7 @@ DIR=MNN make -j16 adb push ./libllm.so /data/local/tmp/MNN/libllm.so adb push ./llm_demo /data/local/tmp/MNN/llm_demo +adb push ./diffusion_demo /data/local/tmp/MNN/diffusion_demo adb push ./libMNN.so /data/local/tmp/$DIR/libMNN.so adb push ./libMNN_CL.so /data/local/tmp/$DIR/libMNN_CL.so adb push ./libMNN_Vulkan.so /data/local/tmp/$DIR/libMNN_Vulkan.so diff --git a/pymnn/examples/MNNLlm/llm_example.py b/pymnn/examples/MNNLlm/llm_example.py new file mode 100644 index 000000000..ec96c0afb --- /dev/null +++ b/pymnn/examples/MNNLlm/llm_example.py @@ -0,0 +1,19 @@ +import MNN.llm as llm +import sys + +if len(sys.argv) < 2: + print('usage: python llm_example.py ') + exit(1) + +config_path = sys.argv[1] +# create model +qwen = llm.create(config_path) +# load model +qwen.load() + +# response stream +out = qwen.response('你好', True) +print(out) + +out_ids = qwen.generate([151644, 872, 198, 108386, 151645, 198, 151644, 77091]) +print(out_ids) diff --git a/pymnn/pip_package/MNN/llm/__init__.py b/pymnn/pip_package/MNN/llm/__init__.py new file mode 100644 index 000000000..f144b3e06 --- /dev/null +++ b/pymnn/pip_package/MNN/llm/__init__.py @@ -0,0 +1,76 @@ +import _mnncengine.llm as _F + +class LLM(_F.LLM): + def load(self, model_dir): + ''' + load model from model_dir + + Parameters + ---------- + model_dir : model path (split) or model name (single) + + Returns + ------- + None + + Example: + ------- + >>> llm.load('../qwen-1.8b-in4/conig.json') + ''' + super.load(model_dir) + + def generate(self, input_ids): + ''' + generate by input_ids + + Parameters + ---------- + input_ids : input token ids, list of int + + Returns + ------- + output_ids : output token ids, list of int + + Example: + ------- + >>> input_ids = [151644, 872, 198, 108386, 151645, 198, 151644, 77091] + >>> output_ids = qwen.generate(input_ids) + ''' + return super.generate(input_ids) + + def response(self, prompt, stream = False): + ''' + response by prompt + + Parameters + ---------- + prompt : input prompt + stream : generate string stream, default is False + + Returns + ------- + res : output string + + Example: + ------- + >>> res = qwen.response('Hello', True) + ''' + return super.response(prompt, stream) + +def create(config_path): + ''' + create LLM instance by `config.json` + + Parameters + ---------- + config_path : config path or model path + + Returns + ------- + llm : LLM instance + + Example: + ------- + >>> qwen = llm.create('./qwen-1.8b-int4/config.json') + ''' + return _F.create(config_path) \ No newline at end of file diff --git a/pymnn/pip_package/build_deps.py b/pymnn/pip_package/build_deps.py index 30be4a31a..8d0297c90 100644 --- a/pymnn/pip_package/build_deps.py +++ b/pymnn/pip_package/build_deps.py @@ -29,6 +29,8 @@ USE_RENDER = False USE_SSE = True USE_OPENMP = False +USE_LLM = False +USE_ARM82 = False if len(sys.argv) > 1 and sys.argv[1] != None: if "trt" in sys.argv[1]: @@ -51,6 +53,10 @@ USE_SSE = False if "openmp" in sys.argv[1]: USE_OPENMP = True + if "llm" in sys.argv[1]: + USE_LLM = True + if "arm82" in sys.argv[1]: + USE_ARM82 = True print ("USE_INTERNAL:", USE_INTERNAL) print ("USE_TRT:", USE_TRT) @@ -62,6 +68,8 @@ print ("USE_RENDER:", USE_RENDER) print ("USE_SSE:", USE_SSE) print ("USE_OPENMP:", USE_OPENMP) +print ("USE_LLM:", USE_LLM) +print ("USE_ARM82:", USE_ARM82) def build_deps(): """ build depency """ @@ -79,6 +87,10 @@ def build_deps(): extra_opts += ' -DMNN_VULKAN=ON -DMNN_VULKAN_IMAGE=OFF' if USE_OPENCL: extra_opts += ' -DMNN_OPENCL=ON' + if USE_LLM: + extra_opts += ' -DMNN_BUILD_LLM=ON -DMNN_LOW_MEMORY=ON -DMNN_SUPPORT_TRANSFORMER_FUSE=ON' + if USE_ARM82: + extra_opts += ' -DMNN_ARM82=ON' extra_opts += ' -DMNN_USE_THREAD_POOL=OFF -DMNN_OPENMP=ON' if USE_OPENMP else ' -DMNN_USE_THREAD_POOL=ON -DMNN_OPENMP=OFF' if IS_WINDOWS: diff --git a/pymnn/pip_package/setup.py b/pymnn/pip_package/setup.py index 6651a76ee..633968edb 100644 --- a/pymnn/pip_package/setup.py +++ b/pymnn/pip_package/setup.py @@ -214,6 +214,9 @@ def configure_extension_build(): engine_include_dirs += [os.path.join(root_dir, "3rd_party", "rapidjson")] # cv include engine_include_dirs += [os.path.join(root_dir, "tools", "cv", "include")] + # llm include + engine_include_dirs += [os.path.join(root_dir, "transformers", "llm", "engine", "include")] + engine_include_dirs += [os.path.join(root_dir, "3rd_party")] engine_include_dirs += [np.get_include()] lib_files = [] @@ -247,6 +250,12 @@ def configure_extension_build(): # add libTorch dependency torch_lib = None cmakecache = os.path.join(root_dir, BUILD_DIR, 'CMakeCache.txt') + # llm + for line in open(cmakecache, 'rt').readlines(): + if 'MNN_BUILD_LLM' in line: + if 'ON' in line: + extra_compile_args += ['-DPYMNN_LLM_API'] + # torch lib for line in open(cmakecache, 'rt').readlines(): if 'TORCH_LIBRARY' in line: torch_lib = os.path.dirname(line[line.find('=')+1:]) diff --git a/pymnn/src/MNN.cc b/pymnn/src/MNN.cc index f7d8dbaf1..1ec9a15e1 100644 --- a/pymnn/src/MNN.cc +++ b/pymnn/src/MNN.cc @@ -66,6 +66,10 @@ using RegularizationMethod = ParameterOptimizer::RegularizationMethod; #endif #endif +#ifdef PYMNN_LLM_API +#include "llm.h" +#endif + #ifdef PYMNN_INTERNAL_SERVING #include #include "internal/monitor_service.h" @@ -1610,7 +1614,7 @@ static PyObject* PyMNNTensor_fromNumpy(PyMNNTensor *self, PyObject *args) { return NULL; } DType dtype = htype2dtype(self->tensor->getType()); - int npy_type = PyArray_TYPE(data); + int npy_type = PyArray_TYPE((const PyArrayObject*)data); int itemsize = getitemsize(dtype, npy_type); PyArrayObject *data_cont= PyArray_GETCONTIGUOUS((PyArrayObject*)data); auto tmpBuffer = PyArray_DATA(data_cont); @@ -1946,7 +1950,7 @@ static PyObject* PyMNNCVImageProcess_convert(PyMNNCVImageProcess *self, PyObject #ifdef PYMNN_NUMPY_USABLE else if(gNumpyValid && PyArray_Check(source)) { // Array Data - int npy_type = PyArray_TYPE(source); + int npy_type = PyArray_TYPE((const PyArrayObject*)source); if(npy_type != NPY_UINT8) { PyErr_SetString(PyExc_Exception, "PyMNNCVImageProcess_convert: only numpy.uint8 is supported for numpy"); @@ -2710,6 +2714,20 @@ PyMODINIT_FUNC MOD_INIT_FUNC(void) { } #endif #endif +#ifdef PYMNN_LLM_API + // llm submodule + auto llm_module = def_submodule(m, "llm"); + if (PyType_Ready(&PyMNNLLM) < 0) { + PyErr_SetString(PyExc_Exception, "initMNN.llm: PyType_Ready PyMNNLLM failed"); + ERROR_RETURN + } + PyModule_AddObject(llm_module, "LLM", (PyObject *)PyType_FindTLSType(&PyMNNLLM)); + // add methods of llm + constexpr int llm_method_num = sizeof(PyMNNLLM_static_methods) / sizeof(PyMethodDef); + for (int i = 0; i < llm_method_num; i++) { + def_method(llm_module, &PyMNNLLM_static_methods[i]); + } +#endif #if PY_MAJOR_VERSION >= 3 return m; diff --git a/pymnn/src/llm.h b/pymnn/src/llm.h new file mode 100644 index 000000000..8e9fffcfd --- /dev/null +++ b/pymnn/src/llm.h @@ -0,0 +1,113 @@ +#include "llm.hpp" + +typedef struct { + PyObject_HEAD + Llm* llm; +} LLM; + +static PyObject* PyMNNLLM_new(struct _typeobject *type, PyObject *args, PyObject *kwds) { + LLM* self = (LLM *)type->tp_alloc(type, 0); + return (PyObject*)self; +} + +static PyObject* Py_str(PyObject *self) { + LLM* llm = (LLM*)self; + if (!llm) { + Py_RETURN_NONE; + } + return toPyObj("llm"); +} + +static PyObject* PyMNNLLM_load(LLM *self, PyObject *args) { + self->llm->load(); + Py_RETURN_NONE; +} + +static PyObject* PyMNNLLM_generate(LLM *self, PyObject *args) { + PyObject *input_ids = nullptr; + if (!PyArg_ParseTuple(args, "O", &input_ids) && isInts(input_ids)) { + Py_RETURN_NONE; + } + auto output_ids = self->llm->generate(toInts(input_ids)); + return toPyObj(output_ids); +} + +static PyObject* PyMNNLLM_response(LLM *self, PyObject *args) { + const char* query = NULL; + int stream = 0; + if (!PyArg_ParseTuple(args, "s|p", &query, &stream)) { + Py_RETURN_NONE; + } + LlmStreamBuffer buffer(nullptr); + std::ostream null_os(&buffer); + auto res = self->llm->response(query, stream ? &std::cout : &null_os); + return string2Object(res); +} + +static PyMethodDef PyMNNLLM_methods[] = { + {"load", (PyCFunction)PyMNNLLM_load, METH_VARARGS, "load model."}, + {"generate", (PyCFunction)PyMNNLLM_generate, METH_VARARGS, "generate `output_ids` by `input_ids`."}, + {"response", (PyCFunction)PyMNNLLM_response, METH_VARARGS, "response `query` without hsitory."}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject PyMNNLLM = { + PyVarObject_HEAD_INIT(NULL, 0) + "LLM", /*tp_name*/ + sizeof(LLM), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + Py_str, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + Py_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "LLM is mnn-llm's `Llm` python wrapper", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyMNNLLM_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyMNNLLM_new, /* tp_new */ +}; + +static PyObject* PyMNNLLM_create(PyObject *self, PyObject *args) { + if (!PyTuple_Size(args)) { + return NULL; + } + const char* path = NULL; + if (!PyArg_ParseTuple(args, "s", &path)) { + return NULL; + } + LLM *llm = (LLM *)PyObject_Call((PyObject*)&PyMNNLLM, PyTuple_New(0), NULL); + if (!llm) { + return NULL; + } + llm->llm = Llm::createLLM(path); + return (PyObject*)llm; +} + +static PyMethodDef PyMNNLLM_static_methods[] = { + {"create", PyMNNLLM_create, METH_VARARGS} +}; \ No newline at end of file diff --git a/pymnn/src/util.h b/pymnn/src/util.h index bd33cc895..4ed57f8ab 100644 --- a/pymnn/src/util.h +++ b/pymnn/src/util.h @@ -222,10 +222,10 @@ DType htype2dtype(halide_type_t type) { } if (type.code == halide_type_int && type.bits == 64) { return DType_INT64; - } + } if (type.code == halide_type_handle) { - return DType_STRING; - } + return DType_STRING; + } return DType_FLOAT; } #define CONVERT(src, dst, f)\ @@ -454,7 +454,7 @@ static vector toVec(PyObject* obj) { if (total_length == 0) { return values; } - int item_size = getnpysize(PyArray_TYPE(obj)); + int item_size = getnpysize(PyArray_TYPE((const PyArrayObject*)obj)); PyArrayObject *obj_cont= PyArray_GETCONTIGUOUS((PyArrayObject*)obj); auto tmpBuffer = PyArray_DATA(obj_cont); if(NULL == tmpBuffer) { @@ -518,7 +518,7 @@ static void* toPtr(PyObject *obj, DType dtype, int64_t& total_length, void* data PyMNN_ERROR_LOG("data size does not match each other"); return data; } - int npy_type = PyArray_TYPE(obj); + int npy_type = PyArray_TYPE((const PyArrayObject*)obj); int itemsize = getitemsize(dtype, npy_type); PyArrayObject *obj_cont= PyArray_GETCONTIGUOUS((PyArrayObject*)obj); auto tmpBuffer = PyArray_DATA(obj_cont); diff --git a/pymnn/test/README.md b/pymnn/test/README.md index 08b4a2d29..20be1dbf2 100644 --- a/pymnn/test/README.md +++ b/pymnn/test/README.md @@ -29,10 +29,10 @@ pip install prettytable python3 benchmark.py ``` -# 6. Playgroud Test (just internal usage) +# 6. Playgroud Test (just internal usage) ```bash # 拷贝AliNNModel所有模型和测试数据到MNN工作台工程下 python scripts/pullTestModel.py --alinnmodel_path ../../../AliNNModel --playground_path playground/playground # 拷贝AliNNModel指定模型(mobilenet, Ranfa)和测试数据到MNN工作台工程下 python scripts/pullTestModel.py --alinnmodel_path ../../../AliNNModel --playground_path playground/playground --models mobilenet Ranfa -``` +``` \ No newline at end of file diff --git a/source/backend/cpu/CPUAttention.cpp b/source/backend/cpu/CPUAttention.cpp index c37d9a3f7..a71472d1f 100644 --- a/source/backend/cpu/CPUAttention.cpp +++ b/source/backend/cpu/CPUAttention.cpp @@ -24,13 +24,16 @@ #define FLOAT16_T float #endif +// reduce the value of 'query' to 'query * FP16_QSCALE', avoid fp16 overflow +#define FP16_QSCALE 0.5 + namespace MNN { template static void prefill_pack(Tensor* query, Tensor* key, Tensor* value, char* query_ptr, char* key_ptr, char* value_ptr, int mMaxLength, int mNumHead, int mKvNumHead, int mHeadDim, int mValueH, - int eP, int hP, int query_e, int key_h, int seq_len, int h, int kv_h) { + int eP, int hP, int query_e, int key_h, int seq_len, int h, int kv_h, float q_scale) { auto query_src = query->host(); auto key_src = key->host(); auto value_src = value->host(); @@ -43,7 +46,7 @@ static void prefill_pack(Tensor* query, Tensor* key, Tensor* value, char* query_ for (int k = 0; k < eP; k++) { int s = i * eP + k; if (s < seq_len) { - query_dst[i * mHeadDim * eP + j * eP + k] = query_src[s * mNumHead * mHeadDim + h * mHeadDim + j]; + query_dst[i * mHeadDim * eP + j * eP + k] = query_src[s * mNumHead * mHeadDim + h * mHeadDim + j] * q_scale; } } } @@ -74,7 +77,7 @@ static void prefill_pack(Tensor* query, Tensor* key, Tensor* value, char* query_ template static void decode_pack(Tensor* query, Tensor* key, Tensor* value, char* query_ptr, char* key_ptr, char* value_ptr, - int mMaxLength, int mPastLength, int mHeadDim, int mValueH, int eP, int hP, int h, int kv_h) { + int mMaxLength, int mPastLength, int mHeadDim, int mValueH, int eP, int hP, int h, int kv_h, float q_scale) { auto query_src = query->host(); auto key_src = key->host(); auto value_src = value->host(); @@ -82,7 +85,7 @@ static void decode_pack(Tensor* query, Tensor* key, Tensor* value, char* query_p auto key_dst = reinterpret_cast(key_ptr); auto value_dst = reinterpret_cast(value_ptr); for (int i = 0; i < mHeadDim; i++) { - query_dst[i * eP] = query_src[h * mHeadDim + i]; + query_dst[i * eP] = query_src[h * mHeadDim + i] * q_scale; } // transpose key: [1, num_head, head_dim] -> numhead, [kv_seq_len/hP, head_dim, hP] int outside_offset = UP_DIV(mPastLength, hP); @@ -164,10 +167,10 @@ static void decode_softmax(float* mask_qk, float* softmax_qk, char* unpack_qk, c } void CPUAttention::allocKVCache() { - if (!mKVCache || mResource->mPastLength < mResource->mMaxLength) { + if (!mKVCache) { return; } - mResource->mMaxLength = mResource->mPastLength + mResource->mExpandChunk; + mResource->mMaxLength = ROUND_UP(mResource->mPastLength, mResource->mExpandChunk); // past_key: [1, numhead, headdim, maxlen] -> numhead, [headdim, maxlen] -> pack_b -> numhead, [maxlen/hP, head_dim, hP] mResource->mPastKey.reset(Tensor::createDevice({mResource->mKvNumHead, UP_DIV(mResource->mMaxLength, hP), mResource->mHeadDim, hP})); // past_value: [1, numhead, maxlen, headdim] -> numhead, [maxlen, headdim] -> pack_b -> numhead, [head_dim/hP, max_len, hP] @@ -202,66 +205,32 @@ void CPUAttention::reallocKVCache() { } mResource->mPastKey.reset(new_key); mResource->mPastValue.reset(new_value); - mTempQK.reset(Tensor::createDevice({mThreadNum, eP + 2, mResource->mMaxLength})); - backend()->onAcquireBuffer(mTempQK.get(), Backend::STATIC); } ErrorCode CPUAttention::onResize(const std::vector& inputs, const std::vector& outputs) { auto core = static_cast(backend())->functions(); - int unit = core->pack; - bytes = core->bytes; core->MNNGetMatMulPackMode(&eP, &lP, &hP); - + unit = core->pack; + bytes = core->bytes; auto query = inputs[0]; - auto key = inputs[1]; - auto value = inputs[2]; - auto mask = inputs[3]; auto shape = query->shape(); int seq_len = shape[1]; mThreadNum = ((CPUBackend *)backend())->threadNumber(); - mIsDecode = seq_len == 1; - if (mResource->mPastLength == 0 || seq_len > 1) { - mResource->mPastLength = seq_len; - } - mResource->mNumHead = shape[2]; - mResource->mKvNumHead = key->shape()[2]; mResource->mHeadDim = shape[3]; - mResource->mScale = 1.0 / sqrt(mResource->mHeadDim); - mResource->mValueH = UP_DIV(mResource->mHeadDim, hP); int query_e = UP_DIV(seq_len, eP); - int key_h = UP_DIV(seq_len, hP); - // mPastLength = 10; - // alloc kv cache - allocKVCache(); - - int tileCount = UP_DIV(mResource->mNumHead, mThreadNum); - - // temp_query mPackQ.reset(Tensor::createDevice({mThreadNum, query_e, mResource->mHeadDim, eP})); mPackQKV.reset(Tensor::createDevice({mThreadNum, UP_DIV(mResource->mHeadDim, unit), seq_len, unit})); - if (mIsDecode) { - mTempQK.reset(Tensor::createDevice({mThreadNum, eP + 2, mResource->mMaxLength})); - backend()->onAcquireBuffer(mTempQK.get(), Backend::DYNAMIC); - } else { - mTempQK.reset(Tensor::createDevice({mThreadNum, 4, seq_len, seq_len})); - backend()->onAcquireBuffer(mTempQK.get(), Backend::DYNAMIC); - } backend()->onAcquireBuffer(mPackQ.get(), Backend::DYNAMIC); backend()->onAcquireBuffer(mPackQKV.get(), Backend::DYNAMIC); backend()->onReleaseBuffer(mPackQ.get(), Backend::DYNAMIC); - backend()->onReleaseBuffer(mTempQK.get(), Backend::DYNAMIC); backend()->onReleaseBuffer(mPackQKV.get(), Backend::DYNAMIC); return NO_ERROR; } ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std::vector& outputs) { auto core = static_cast(backend())->functions(); - int unit = core->pack; - bytes = core->bytes; - core->MNNGetMatMulPackMode(&eP, &lP, &hP); auto matmulUnit = core->MNNPackedMatMul; auto matmulRemain = core->MNNPackedMatMulRemain; - auto query = inputs[0]; auto key = inputs[1]; auto value = inputs[2]; @@ -271,23 +240,34 @@ ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std: int seq_len = shape[1]; mThreadNum = ((CPUBackend *)backend())->threadNumber(); mIsDecode = seq_len == 1; - if (mResource->mPastLength == 0 || seq_len > 1) { - mResource->mPastLength = seq_len; - } mResource->mNumHead = shape[2]; mResource->mKvNumHead = key->shape()[2]; int group_size = mResource->mNumHead / mResource->mKvNumHead; mResource->mHeadDim = shape[3]; mResource->mScale = 1.0 / sqrt(mResource->mHeadDim); + // reduce the value of 'query' to avoid fp16 overflow + float q_scale = 1.0; + if (bytes == 2) { + q_scale = FP16_QSCALE; + mResource->mScale /= q_scale; + } mResource->mValueH = UP_DIV(mResource->mHeadDim, hP); int query_e = UP_DIV(seq_len, eP); int key_h = UP_DIV(seq_len, hP); - // mPastLength = 10; - int tileCount = UP_DIV(mResource->mNumHead, mThreadNum); - // try calloc kv cache - mPrefill = [=](int tId){ + std::shared_ptr mTempQK; + if (mIsDecode) { + reallocKVCache(); + mTempQK.reset(Tensor::createDevice({mThreadNum, eP + 2, mResource->mPastLength + 1})); + } else { + mResource->mPastLength = seq_len; + allocKVCache(); + mTempQK.reset(Tensor::createDevice({mThreadNum, 4, seq_len, seq_len})); + } + backend()->onAcquireBuffer(mTempQK.get(), Backend::STATIC); + + std::function mPrefill = [=](int tId){ auto pack_q = mPackQ->host() + tId * query_e * mResource->mHeadDim * eP * bytes; auto pack_qk = mTempQK->host() + tId * 4 * seq_len * seq_len * bytes; auto unpack_qk = pack_qk + seq_len * seq_len * 2 * bytes; @@ -302,9 +282,9 @@ ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std: auto key_dst = mResource->mPastKey->host() + kv_h * UP_DIV(mResource->mMaxLength, hP) * mResource->mHeadDim * hP * bytes; auto value_dst = mResource->mPastValue->host() + kv_h * mResource->mValueH * mResource->mMaxLength * hP * bytes; if (bytes == 2) { - prefill_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mNumHead, mResource->mKvNumHead, mResource->mHeadDim, mResource->mValueH, eP, hP, query_e, key_h, seq_len, h, kv_h); + prefill_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mNumHead, mResource->mKvNumHead, mResource->mHeadDim, mResource->mValueH, eP, hP, query_e, key_h, seq_len, h, kv_h, q_scale); } else { - prefill_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mNumHead, mResource->mKvNumHead, mResource->mHeadDim, mResource->mValueH, eP, hP, query_e, key_h, seq_len, h, kv_h); + prefill_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mNumHead, mResource->mKvNumHead, mResource->mHeadDim, mResource->mValueH, eP, hP, query_e, key_h, seq_len, h, kv_h, q_scale); } // query @ key int loop_e = seq_len / eP; @@ -331,7 +311,7 @@ ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std: parameters[5] = 0; matmulRemain((float*)(pack_qk + (loop_e * eP * unit) * bytes), (float*)(pack_q + (loop_e * mResource->mHeadDim * eP) * bytes), (float*)key_dst, remain, parameters, nullptr, nullptr, nullptr, nullptr); } - int area_offset[1] {seq_len}; + int area_offset[2] {seq_len, 0}; core->MNNUnpackCUnitTranspose((float*)unpack_qk, (float*)pack_qk, seq_len, seq_len, area_offset); // div scale and mask auto mask_ptr = mask->host(); @@ -373,7 +353,7 @@ ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std: } }; - mDecode = [=](int tId) { + std::function mDecode = [=](int tId) { int kv_seq_len = mResource->mPastLength + 1; auto pack_q = mPackQ->host() + tId * mResource->mHeadDim * eP * bytes; auto pack_qk = mTempQK->host() + tId * (eP + 2) * kv_seq_len * bytes; @@ -389,9 +369,9 @@ ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std: auto value_dst = mResource->mPastValue->host() + kv_h * mResource->mValueH * mResource->mMaxLength * hP * bytes; // pack for matmul if (bytes == 2) { - decode_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mPastLength, mResource->mHeadDim, mResource->mValueH, eP, hP, h, kv_h); + decode_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mPastLength, mResource->mHeadDim, mResource->mValueH, eP, hP, h, kv_h, q_scale); } else { - decode_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mPastLength, mResource->mHeadDim, mResource->mValueH, eP, hP, h, kv_h); + decode_pack(query, key, value, pack_q, key_dst, value_dst, mResource->mMaxLength, mResource->mPastLength, mResource->mHeadDim, mResource->mValueH, eP, hP, h, kv_h, q_scale); } // query @ key: [1, head_dim] @ [head_dim, kv_seq_len] -> [1, kv_seq_len] size_t shapeParameters[6]; @@ -403,7 +383,7 @@ ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std: parameters[4] = 0; parameters[5] = 0; matmulRemain((float*)pack_qk, (float*)pack_q, (float*)key_dst, seq_len, parameters, nullptr, nullptr, nullptr, nullptr); - int area_offset[1] {seq_len}; + int area_offset[2] {seq_len, 0}; core->MNNUnpackCUnitTranspose((float*)unpack_qk, (float*)pack_qk, seq_len, kv_seq_len, area_offset); if (bytes == 2) { decode_softmax(mask_qk, softmax_qk, unpack_qk, pack_qk, mResource->mScale, eP, kv_seq_len); @@ -426,14 +406,16 @@ ErrorCode CPUAttention::onExecute(const std::vector& inputs, const std: core->MNNUnpackCUnitTranspose((float*)dst_ptr, (float*)pack_qkv, 1, mResource->mHeadDim, area_offset); } }; - mFunction = mIsDecode ? mDecode : mPrefill; - reallocKVCache(); - // compute + + std::function mFunction = mIsDecode ? mDecode : mPrefill; MNN_CONCURRENCY_BEGIN(tId, mThreadNum) { mFunction((int)tId); } MNN_CONCURRENCY_END(); - mResource->mPastLength += mIsDecode; + if(mIsDecode) { + mResource->mPastLength++; + } + backend()->onReleaseBuffer(mTempQK.get(), Backend::STATIC); return NO_ERROR; } diff --git a/source/backend/cpu/CPUAttention.hpp b/source/backend/cpu/CPUAttention.hpp index 6e3154db7..bc48de6b4 100644 --- a/source/backend/cpu/CPUAttention.hpp +++ b/source/backend/cpu/CPUAttention.hpp @@ -39,9 +39,8 @@ class CPUAttention : public Execution { bool mKVCache; int mThreadNum = 1; std::shared_ptr mResource; - std::shared_ptr mTempQK, mPackQ, mPackQKV; - int eP, lP, hP, bytes; - std::function mFunction, mPrefill, mDecode; + std::shared_ptr mPackQ, mPackQKV; + int eP, lP, hP, bytes, unit; }; } // namespace MNN diff --git a/source/backend/cpu/CPUBackend.cpp b/source/backend/cpu/CPUBackend.cpp index 0a9637377..66c349c37 100644 --- a/source/backend/cpu/CPUBackend.cpp +++ b/source/backend/cpu/CPUBackend.cpp @@ -481,7 +481,11 @@ void CPUBackend::onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) auto& srcBuffer = srcTensor->buffer(); auto& dstBuffer = dstTensor->buffer(); - MNN_ASSERT(srcBuffer.dimensions == dstBuffer.dimensions); + if (srcBuffer.dimensions != dstBuffer.dimensions ) { + if (srcBuffer.dim[srcBuffer.dimensions - 1].extent != 1 && dstBuffer.dim[dstBuffer.dimensions - 1].extent != 1) { + MNN_ERROR("srcBuffer dimension not equal to dstBuffer, can't copy buffer\n"); + } + } if (srcTensor->getDimensionType() == dstTensor->getDimensionType()) { for (int i = 0; i < srcBuffer.dimensions; ++i) { MNN_ASSERT(srcBuffer.dim[i].extent <= dstBuffer.dim[i].extent); diff --git a/source/backend/cpu/CPUUnary.cpp b/source/backend/cpu/CPUUnary.cpp index a046b7f4d..b727f1c3e 100644 --- a/source/backend/cpu/CPUUnary.cpp +++ b/source/backend/cpu/CPUUnary.cpp @@ -551,6 +551,7 @@ class CPUUnaryCreator : public CPUBackend::Creator { proc = core->MNNSelectUnaryFunctionForFloat(op->main_as_UnaryOp()->opType(), static_cast(backend)->precisionMode()); } if (nullptr == proc && nullptr == procInt8 && nullptr == op->main_as_UnaryOp()->tableInt8()) { + MNN_ERROR("ERROR: Unary Op can not execute\n"); return nullptr; } return new CPUUnary(backend, proc, procInt8, op); diff --git a/source/backend/metal/AllShader.cpp b/source/backend/metal/AllShader.cpp index 2fb7cacc2..3a695797e 100644 --- a/source/backend/metal/AllShader.cpp +++ b/source/backend/metal/AllShader.cpp @@ -558,235 +558,6 @@ const char* shader_MetalReduction_metal = "define_reduce(max);\n" "define_reduce(prod);\n" ; -const char* shader_MetalBackend_metal = -"struct tensor_shape {\n" -" int size;\n" -" int channel;\n" -" int batch;\n" -" int batch_slices;\n" -"};\n" -"struct Limit {\n" -" uint4 size;\n" -"};\n" -"kernel void upcast_float4(const device M4 *in [[buffer(0)]],\n" -" device float4 *out [[buffer(1)]],\n" -" constant Limit& limit [[buffer(2)]],\n" -" uint gid [[thread_position_in_grid]]) {\n" -" if (gid\n" -"static inline void template_NHWC_to_NC4HW4(const device IType *in,device OType *out,constant tensor_shape &s,uint2 gid) {\n" -" int b=gid.y % s.batch;\n" -" int z=gid.y/s.batch;\n" -" int c=z*4;\n" -" \n" -" auto off_in=in+b*s.size*s.channel+int(gid.x)*s.channel+c;\n" -" auto off_out=out+int(gid.y)*s.size+int(gid.x);\n" -" off_out[0]=OType(c+0(in,out,s,gid);\n" -"}\n" -"kernel void downcast_f_NHWC_to_NC4HW4(const device float *in [[buffer(0)]],\n" -" device M4 *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_u_NHWC_to_NC4HW4(const device uchar *in [[buffer(0)]],\n" -" device uchar4 *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_f_NHWC_to_NC4HW4(const device M *in [[buffer(0)]],\n" -" device M4 *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"template \n" -"static inline void template_NC4HW4_to_NHWC(const device IType *in,device OType *out,constant tensor_shape &s,uint2 gid) {\n" -" int b=gid.y % s.batch;\n" -" int z=gid.y/s.batch;\n" -" int c=z*4;\n" -" auto off_in=in+int(gid.y)*s.size+int(gid.x);\n" -" auto off_out=out+b*s.size*s.channel+int(gid.x)*s.channel+c;\n" -" \n" -" IType v4=off_in[0];\n" -" /* if (1) */ off_out[0]=v4[0];\n" -" if (c+1(in,out,s,gid);\n" -"}\n" -"kernel void downcast_f_NC4HW4_to_NHWC(const device float4 *in [[buffer(0)]],\n" -" device M *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_u_NC4HW4_to_NHWC(const device uchar4 *in [[buffer(0)]],\n" -" device uchar *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_f_NC4HW4_to_NHWC(const device M4 *in [[buffer(0)]],\n" -" device M *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"template \n" -"static inline void template_NCHW_to_NC4HW4(const device IType *in,device OType *out,constant tensor_shape &s,uint2 gid) {\n" -" int b=gid.y % s.batch;\n" -" int z=gid.y/s.batch;\n" -" int c=z*4;\n" -" \n" -" auto off_in=in+(b*s.channel+c)*s.size+int(gid.x);\n" -" auto off_out=out+int(gid.y)*s.size+int(gid.x);\n" -" off_out[0]=OType(c+0(in,out,s,gid);\n" -"}\n" -"kernel void downcast_f_NCHW_to_NC4HW4(const device float *in [[buffer(0)]],\n" -" device M4 *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_u_NCHW_to_NC4HW4(const device uchar *in [[buffer(0)]],\n" -" device uchar4 *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_f_NCHW_to_NC4HW4(const device M *in [[buffer(0)]],\n" -" device M4 *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"template \n" -"static inline void template_NC4HW4_to_NCHW(const device IType *in,device OType *out,constant tensor_shape &s,uint2 gid) {\n" -" int b=gid.y % s.batch;\n" -" int z=gid.y/s.batch;\n" -" int c=z*4;\n" -" \n" -" auto off_in=in+int(gid.y)*s.size+int(gid.x);\n" -" auto off_out=out+(b*s.channel+c)*s.size+int(gid.x);\n" -" IType v4=off_in[0];\n" -" /* if (1) */ off_out[0*s.size]=v4.x;\n" -" if (c+1(in,out,s,gid);\n" -"}\n" -"kernel void downcast_f_NC4HW4_to_NCHW(const device float4 *in [[buffer(0)]],\n" -" device M *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_u_NC4HW4_to_NCHW(const device uchar4 *in [[buffer(0)]],\n" -" device uchar *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"kernel void cvt_f_NC4HW4_to_NCHW(const device M4 *in [[buffer(0)]],\n" -" device M *out [[buffer(1)]],\n" -" constant tensor_shape &s [[buffer(2)]],\n" -" uint2 gid [[thread_position_in_grid]]) {\n" -" if ((int)gid.x(in,out,s,gid);\n" -"}\n" -"template\n" -"static inline void template_NHWC_to_NCHW(const device IType* in,\n" -" device OType* out,constant tensor_shape &s,uint2 gid) {\n" -" int b=gid.y % s.batch;\n" -" int c4=gid.y/s.batch;\n" -" \n" -" auto in_off=(b*s.size+gid.x)*s.channel+c4*4;\n" -" auto out_off=(b*s.channel+c4*4)*s.size+gid.x;\n" -" \n" -" out[out_off]=in[in_off];\n" -" if(c4*4+1(in,out,s,gid);\n" -"}\n" -"template\n" -"static inline void template_NCHW_to_NHWC(const device IType* in,\n" -" device OType* out,constant tensor_shape &s,uint2 gid) {\n" -" int b=gid.y % s.batch;\n" -" int c4=gid.y/s.batch;\n" -" \n" -" auto in_off=(b*s.channel+c4*4)*s.size+gid.x;\n" -" auto out_off=(b*s.size+gid.x)*s.channel+c4*4;\n" -" \n" -" out[out_off]=in[in_off];\n" -" if(c4*4+1(in,out,s,gid);\n" -"}\n" -; const char* shader_MetalSoftmax_metal = "struct softmax_shape {\n" " int inside_size;\n" diff --git a/source/backend/metal/AllShader.hpp b/source/backend/metal/AllShader.hpp index d430897b0..cc9faa50f 100644 --- a/source/backend/metal/AllShader.hpp +++ b/source/backend/metal/AllShader.hpp @@ -5,7 +5,6 @@ extern const char* shader_MetalConvolutionDepthwise_metal; extern const char* shader_MetalConvolutionActivation_metal; extern const char* shader_MetalConvolution_metal; extern const char* shader_MetalReduction_metal; -extern const char* shader_MetalBackend_metal; extern const char* shader_MetalSoftmax_metal; extern const char* shader_MetalLayerNorm_metal; extern const char* shader_MetalConvolutionWinograd_metal; diff --git a/source/backend/metal/MetalBackend.hpp b/source/backend/metal/MetalBackend.hpp index 786a89351..589dd5fff 100644 --- a/source/backend/metal/MetalBackend.hpp +++ b/source/backend/metal/MetalBackend.hpp @@ -235,9 +235,8 @@ class MetalBackend : public Backend { private: mutable id mHostBuffer = nullptr; - void onCopyHostToDevice(const Tensor *src, const Tensor *dst) const; - void onCopyDeviceToHost(const Tensor *src, const Tensor *dst) const; - void onCopyDeviceToDevice(const Tensor *src, const Tensor *dst, id encoder, id shape) const; + // hostmask: 0: no host, 1: src is host, 2: dst is host + void onCopyDeviceToDevice(const Tensor *src, const Tensor *dst, id encoder, id shape, int hostmask = 0) const; bool mUseFloatAsFp16; bool mIsIphone = false; BufferAllocator* mCurrentAllocator = nullptr; diff --git a/source/backend/metal/MetalBackend.mm b/source/backend/metal/MetalBackend.mm index 64187b36c..57d800910 100644 --- a/source/backend/metal/MetalBackend.mm +++ b/source/backend/metal/MetalBackend.mm @@ -342,103 +342,183 @@ MemChunk chunk() override { void MetalBackend::returnConstBuffer(id buffer) const { mHoldBuffers.push(buffer); } - -MTLSize getTensorShape(id shape, const Tensor *tensor) { - int s = 1, c = 1, b = 1; - if (tensor->dimensions() == 4) { - s = tensor->width() * tensor->height(); - c = tensor->channel(); - b = tensor->batch(); - } else if (tensor->dimensions() >= 2){ - for (int i=2; idimensions(); ++i) { +static inline void _getNCPlane(const Tensor* tensor, int& s, int& c, int& b) { + auto format = TensorUtils::getDescribe(tensor)->dimensionFormat; + s = 1, c = 1, b = 1; + b = tensor->length(0); + if (format == MNN_DATA_FORMAT_NHWC) { + c = tensor->length(tensor->dimensions()-1); + for (int i=1; idimensions()-1; ++i) { s *= tensor->length(i); } + } else { c = tensor->length(1); - b = tensor->length(0); + for (int i=2; idimensions(); ++i) { + s *= tensor->length(i); + } } - +} +MTLSize getTensorShape(id shape, const Tensor *tensor) { + auto format = TensorUtils::getDescribe(tensor)->dimensionFormat; + int s, b, c; + _getNCPlane(tensor, s, c, b); int z = UP_DIV(c, 4); // shape - ((int *)shape.contents)[0] = s; + ((int *)shape.contents)[0] = b; ((int *)shape.contents)[1] = c; - ((int *)shape.contents)[2] = b; - ((int *)shape.contents)[3] = b * z; - + ((int *)shape.contents)[2] = s; + ((int *)shape.contents)[3] = 1; + + // stride + if (format == MNN_DATA_FORMAT_NHWC) { + ((int *)shape.contents)[4] = s * c; + ((int *)shape.contents)[5] = 1; + ((int *)shape.contents)[6] = c; + ((int *)shape.contents)[7] = 1; + } else { + ((int *)shape.contents)[4] = s * c; + ((int *)shape.contents)[5] = s; + ((int *)shape.contents)[6] = 1; + ((int *)shape.contents)[7] = 1; + } // threads - MTLSize threads = {(NSUInteger)s, (NSUInteger)b * z, 1}; + MTLSize threads = {(NSUInteger)s * b * z, 1, 1}; return threads; } +static const char* gTranspose = R"metal( +#include +#include +using namespace metal; +struct tensor_shape { + uint4 size; // n, c, plane, 1 + uint4 stride; +}; +kernel void main0(const device IType* in [[buffer(0)]], device OType* out [[buffer(1)]], constant tensor_shape &uConstant [[buffer(2)]], uint gid [[thread_position_in_grid]]) { + int channel = uConstant.size.y; + if (gid < channel * uConstant.size.x * uConstant.size.z) { + int tmp = gid % (channel * uConstant.size.x); + int x = gid / (channel * uConstant.size.x); + int b = tmp / channel; + int c = tmp % channel; + int outPos = b * uConstant.size.y * uConstant.size.z + c * uConstant.size.z + x; + int inPos = b * uConstant.size.y * uConstant.size.z + c + x * uConstant.size.y; + out[outPos] = (OType)(in[inPos]); + } +})metal"; -enum MetalCastType : int { - // no cast - None = 0, - // metal float to float - Up, - // float to metal float - Down +static const char* gNC4HW4Convert = R"metal( +#include +#include +using namespace metal; +struct tensor_shape { + uint4 size; // n, c, plane, 1 + uint4 stride; }; +kernel void main0(const device IType* in [[buffer(0)]], device OType* out [[buffer(1)]], constant tensor_shape &uConstant [[buffer(2)]], uint gid [[thread_position_in_grid]]) { + int channelC4 = (uConstant.size.y + 3) / 4; + if (gid < channelC4 * uConstant.size.x * uConstant.size.z) + { + int3 pos; + pos.z = gid % (channelC4 * uConstant.size.x); + pos.y = gid / (channelC4 * uConstant.size.x); + pos.x = 0; + int batchIndex = pos.z / channelC4; + int zDiv4 = pos.z % channelC4; + + int lastZ = uConstant.size.y / 4; + int cIndex = uConstant.size.y % 4; + + int z = zDiv4*4; + int basicOffset = 0 + + batchIndex*uConstant.stride.x + + z * uConstant.stride.y + + pos.y * uConstant.stride.z + ; +#ifdef MNN_OUTPUT_C4 + OType color = OType(0); + if(zDiv4 == lastZ) + { + if(cIndex == 1) + { + color.r = in[basicOffset+0]; + color.g = 0.0; + color.b = 0.0; + color.a = 0.0; + } + else if(cIndex == 2) + { + color.r = in[basicOffset+0]; + color.g = in[basicOffset+1*uConstant.stride.y]; + color.b = 0.0; + color.a = 0.0; + } + else + { + color.r = in[basicOffset+0]; + color.g = in[basicOffset+1*uConstant.stride.y]; + color.b = in[basicOffset+2*uConstant.stride.y]; + color.a = 0.0; + } + } + else + { + color.r = in[basicOffset+0]; + color.g = in[basicOffset+1*uConstant.stride.y]; + color.b = in[basicOffset+2*uConstant.stride.y]; + color.a = in[basicOffset+3*uConstant.stride.y]; + } -static NSString *kernelForConvert(halide_type_t type, MNN_DATA_FORMAT from, MNN_DATA_FORMAT to, MetalCastType cast) { - if (type.code == halide_type_float) { - NSString *map[3][MNN_DATA_FORMAT_MAX + 1][MNN_DATA_FORMAT_MAX + 1] = { - // none + out[0 + + pos.y + + uConstant.size.x * uConstant.size.z*zDiv4 + + batchIndex*uConstant.size.z + ] = color; +#else + IType color = in[0 + + pos.y + + uConstant.size.x * uConstant.size.z*zDiv4 + + batchIndex*uConstant.size.z + ]; + if(zDiv4 == lastZ) + { + if(cIndex == 1) { - // from MNN_DATA_FORMAT_NCHW - {nil, nil, @"cvt_f_NCHW_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NHWC - {nil, nil, @"cvt_f_NHWC_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NC4HW4 - {@"cvt_f_NC4HW4_to_NCHW", @"cvt_f_NC4HW4_to_NHWC", nil, nil, nil}, - // from MNN_DATA_FORMAT_NHWC4 - {nil, nil, nil, nil, nil}, - // from MNN_DATA_FORMAT_UNKNOWN - {nil, nil, nil, nil, nil}, - }, - // up + out[basicOffset+0*uConstant.stride.y] = color.r; + } + else if(cIndex == 2) { - // from MNN_DATA_FORMAT_NCHW - {nil, nil, @"upcast_f_NCHW_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NHWC - {@"upcast_f_NHWC_to_NCHW", nil, @"upcast_f_NHWC_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NC4HW4 - {@"upcast_f_NC4HW4_to_NCHW", @"upcast_f_NC4HW4_to_NHWC", nil, nil, nil}, - // from MNN_DATA_FORMAT_NHWC4 - {nil, nil, nil, nil, nil}, - // from MNN_DATA_FORMAT_UNKNOWN - {nil, nil, nil, nil, nil}, - }, - // down + out[basicOffset+0*uConstant.stride.y] = color.r; + out[basicOffset+1*uConstant.stride.y] = color.g; + } + else { - // from MNN_DATA_FORMAT_NCHW - {nil, @"downcast_f_NCHW_to_NHWC", @"downcast_f_NCHW_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NHWC - {nil, nil, @"downcast_f_NHWC_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NC4HW4 - {@"downcast_f_NC4HW4_to_NCHW", @"downcast_f_NC4HW4_to_NHWC", nil, nil, nil}, - // from MNN_DATA_FORMAT_NHWC4 - {nil, nil, nil, nil, nil}, - // from MNN_DATA_FORMAT_UNKNOWN - {nil, nil, nil, nil, nil}, - }, - }; - return map[cast][from][to]; - } else { - NSString *map[MNN_DATA_FORMAT_MAX + 1][MNN_DATA_FORMAT_MAX + 1] = { - // from MNN_DATA_FORMAT_NCHW - {nil, nil, @"cvt_u_NCHW_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NHWC - {nil, nil, @"cvt_u_NHWC_to_NC4HW4", nil, nil}, - // from MNN_DATA_FORMAT_NC4HW4 - {@"cvt_u_NC4HW4_to_NCHW", @"cvt_u_NC4HW4_to_NHWC", nil, nil, nil}, - // from MNN_DATA_FORMAT_NHWC4 - {nil, nil, nil, nil, nil}, - // from MNN_DATA_FORMAT_UNKNOWN - {nil, nil, nil, nil, nil}, - }; - return map[from][to]; + out[basicOffset+0*uConstant.stride.y] = color.r; + out[basicOffset+1*uConstant.stride.y] = color.g; + out[basicOffset+2*uConstant.stride.y] = color.b; + } + } + else + { + out[basicOffset+0*uConstant.stride.y] = color.r; + out[basicOffset+1*uConstant.stride.y] = color.g; + out[basicOffset+2*uConstant.stride.y] = color.b; + out[basicOffset+3*uConstant.stride.y] = color.a; + } +#endif } } +)metal"; + +static const char* gCopy = R"metal( +#include +#include +using namespace metal; +kernel void main0(const device IType *in [[buffer(0)]], device OType *out [[buffer(1)]], constant uint4& limit [[buffer(2)]], uint gid [[thread_position_in_grid]]) { + if (gid < limit.x) { + out[int(gid)] = (OType)in[int(gid)]; + } +})metal"; void MetalBackend::onResizeBegin() { mFrameEncodeCache = false; @@ -459,207 +539,146 @@ MTLSize getTensorShape(id shape, const Tensor *tensor) { return mCurrentAllocator->compute(); } -void MetalBackend::onCopyHostToDevice(const Tensor *src, const Tensor *dst) const { - auto ctx = (__bridge MNNMetalContext *)context(); - auto sfmt = TensorUtils::getDescribe(src)->dimensionFormat; - auto dfmt = TensorUtils::getDescribe(dst)->dimensionFormat; - auto device = (id)((MetalRuntimeAllocator::MetalBufferAlloc *) (dst->deviceId()))->getBuffer(); - auto floats = src->getType().code == halide_type_float; - // For command queue from user, need user to make sure last frame's gpu work is ready - bool needWait = !mRuntime->userSync(); - // cast - if (sfmt == dfmt || src->dimensions() <= 1) { - if (floats && mUseFloatAsFp16) { - NSUInteger size = src->elementSize(); - auto sizeC4 = UP_DIV(size, 4); - auto host = this->getHostBuffer(sizeC4 * 4 * sizeof(float)); - if (needWait) { - wait(); - } - memcpy(host.contents, src->host(), src->size()); - unsigned int limits[] = { - (unsigned int)sizeC4, - 1, - 1, - 1 - }; - ::memcpy(mShapeH2D.contents, limits, sizeof(limits)); - auto encoder = [getCommandBufferForBufferCopy() computeCommandEncoder]; - auto pipeline = [ctx pipelineWithName:@"downcast_float4" fp16:mUseFloatAsFp16]; - [encoder setComputePipelineState:pipeline]; - - [encoder setBuffer:host offset:0 atIndex:0]; - [encoder setBuffer:device offset:TensorUtils::getDescribe(dst)->extra.offset atIndex:1]; - [encoder setBuffer:mShapeH2D offset:0 atIndex:2]; - //[ctx dispatchEncoder:encoder threads:{sizeC4, 1, 1} bandwidth:bandwidth]; - std::pair threads; - threads.first = {sizeC4, 1, 1}; - threads.second = {[pipeline maxTotalThreadsPerThreadgroup], 1, 1}; - threads.second.width = threads.second.width <= threads.first.width ? threads.second.width : threads.first.width; - threads.first.width = UP_DIV(threads.first.width, threads.second.width); - [encoder dispatchThreadgroups:threads.first threadsPerThreadgroup:threads.second]; - [encoder endEncoding]; - commit(); - //[ctx wait]; +static std::string _getType(const halide_type_t& type, MNN_DATA_FORMAT format, bool useFp16AsFp32) { + std::string res; + if (type.code == halide_type_float) { + if (useFp16AsFp32) { + res = "half"; } else { - if (needWait) { - wait(); - } - memcpy((uint8_t*)device.contents + TensorUtils::getDescribe(dst)->extra.offset, src->host(), src->size()); + res = "float"; } - } - // convert - else { - - auto buffer = getHostBuffer(src->elementSize() * sizeof(float)); - if (needWait) { - wait(); - } - auto size = getTensorShape(mShapeH2D, src); - memcpy(buffer.contents, src->host(), src->size()); - auto encoder = [getCommandBufferForBufferCopy() computeCommandEncoder]; - auto kernel = kernelForConvert(src->getType(), sfmt, dfmt, Down); - MNN_ASSERT(kernel != nil); // unsupported sfmt to dfmt - auto pipeline = [ctx pipelineWithName:kernel fp16:mUseFloatAsFp16]; - [encoder setComputePipelineState:pipeline]; - - [encoder setBuffer:buffer offset:0 atIndex:0]; - [encoder setBuffer:device offset:TensorUtils::getDescribe(dst)->extra.offset atIndex:1]; - [encoder setBuffer:mShapeH2D offset:0 atIndex:2]; - auto gl = [ctx computeBestGroupAndLocal:pipeline threads:size]; - [encoder dispatchThreadgroups:gl.first threadsPerThreadgroup:gl.second]; - [encoder endEncoding]; - commit(); - //[ctx wait]; - } -} - -void MetalBackend::onCopyDeviceToHost(const Tensor *src, const Tensor *dst) const { - auto ctx = (__bridge MNNMetalContext *)context(); - auto sfmt = TensorUtils::getDescribe(src)->dimensionFormat; - auto dfmt = TensorUtils::getDescribe(dst)->dimensionFormat; - auto device = (id)((MetalRuntimeAllocator::MetalBufferAlloc *)src->deviceId())->getBuffer(); - auto floats = src->getType().code == halide_type_float; - // cast - if (sfmt == dfmt || src->dimensions() <= 1) { - if (floats && mUseFloatAsFp16) { - auto eleSize = dst->elementSize(); - eleSize = UP_DIV(eleSize, 4) * 4; - auto buffer = getHostBuffer(eleSize * dst->getType().bytes()); - - NSUInteger size = src->elementSize(); - auto encoder = [getCommandBufferForBufferCopy() computeCommandEncoder]; - auto pipeline = [ctx pipelineWithName:@"upcast_float4" fp16:mUseFloatAsFp16]; - [encoder setComputePipelineState:pipeline]; - [encoder setBuffer:device offset:TensorUtils::getDescribe(src)->extra.offset atIndex:0]; - [encoder setBuffer:buffer offset:0 atIndex:1]; - auto sizeC4 = UP_DIV(size, 4); - unsigned int limits[] = { - (unsigned int)sizeC4, - 1, - 1, - 1 - }; - ::memcpy(mShapeD2H.contents, limits, sizeof(limits)); - [encoder setBuffer:mShapeD2H offset:0 atIndex:2]; - //[ctx dispatchEncoder:encoder threads:{sizeC4, 1, 1} bandwidth:bandwidth]; - std::pair threads; - threads.first = {sizeC4, 1, 1}; - threads.second = {[pipeline maxTotalThreadsPerThreadgroup], 1, 1}; - threads.second.width = threads.second.width <= threads.first.width ? threads.second.width : threads.first.width; - threads.first.width = UP_DIV(threads.first.width, threads.second.width); - [encoder dispatchThreadgroups:threads.first threadsPerThreadgroup:threads.second]; - - [encoder endEncoding]; - commit(); - wait(); - - memcpy(dst->host(), buffer.contents, dst->size()); - } else { - commit(); - wait(); - memcpy(dst->host(), (uint8_t*)device.contents + TensorUtils::getDescribe(src)->extra.offset, dst->size()); + } else { + switch (type.bytes()) { + case 1: + res = "char"; + break; + case 2: + res = "short"; + break; + case 4: + res = "int"; + break; + default: + MNN_ASSERT(false); + break; } } - // convert - else { - auto size = getTensorShape(mShapeD2H, src); - auto buffer = getHostBuffer(dst->size()); - auto encoder = [getCommandBufferForBufferCopy() computeCommandEncoder]; - auto kernel = kernelForConvert(src->getType(), sfmt, dfmt, Up); - MNN_ASSERT(kernel != nil); // unsupported sfmt to dfmt - - auto pipeline = [ctx pipelineWithName:kernel fp16:mUseFloatAsFp16]; - [encoder setComputePipelineState:pipeline]; - [encoder setBuffer:device offset:TensorUtils::getDescribe(src)->extra.offset atIndex:0]; - [encoder setBuffer:buffer offset:0 atIndex:1]; - [encoder setBuffer:mShapeD2H offset:0 atIndex:2]; - auto gl = [ctx computeBestGroupAndLocal:pipeline threads:size]; - [encoder dispatchThreadgroups:gl.first threadsPerThreadgroup:gl.second]; - [encoder endEncoding]; - commit(); - wait(); - memcpy(dst->host(), buffer.contents, dst->size()); + if (format == MNN_DATA_FORMAT_NC4HW4) { + return res + "4"; } + return res; } -static const char* gCopy = R"metal( -#include -#include -using namespace metal; -kernel void main0(const device int4 *in [[buffer(0)]], device int4 *out [[buffer(1)]], constant uint4& limit [[buffer(2)]], uint gid [[thread_position_in_grid]]) { - if (gid < limit.x) { - out[int(gid)] = in[int(gid)]; - } -})metal"; void MetalBackend::onCopyDeviceToDevice(const Tensor *src, const Tensor *dst, - id encoder, id shape) const { + id encoder, id shape, int castType) const { auto ctx = (__bridge MNNMetalContext *)context(); auto standalone = encoder == nil; - encoder = encoder ?: [getCommandBufferForBufferCopy() computeCommandEncoder]; - auto sfmt = TensorUtils::getDescribe(src)->dimensionFormat; - auto dfmt = TensorUtils::getDescribe(dst)->dimensionFormat; - + encoder = encoder ?: [getCommandBufferForBufferCopy() computeCommandEncoder]; + auto sfmt = TensorUtils::getDescribe(src)->dimensionFormat; + auto dfmt = TensorUtils::getDescribe(dst)->dimensionFormat; + if (shape == nil) { + shape = getConstBuffer(8 * sizeof(int)); + } // copy if (sfmt == dfmt || src->dimensions() <= 1) { - auto size = dst->usize(); - if (mUseFloatAsFp16 && dst->getType().code == halide_type_float) { - size = size / 2; - } - size = UP_DIV(size, (4 * sizeof(float))); + auto srcType = _getType(src->getType(), MNN_DATA_FORMAT_NC4HW4, mUseFloatAsFp16 && castType != 1); + auto dstType = _getType(dst->getType(), MNN_DATA_FORMAT_NC4HW4, mUseFloatAsFp16 && castType != 2); + auto size = dst->elementSize(); + size = UP_DIV(size, 4); std::vector keys = { - "copyC4" + "copyC4", + srcType, + dstType }; id pipeline = mRuntime->findPipeline(keys); if (nil == pipeline) { - pipeline = makeComputePipelineWithSourceOption(gCopy, "main0", nil); + MTLCompileOptions *option = [[MTLCompileOptions alloc] init]; + auto dic = [NSMutableDictionary dictionaryWithCapacity:0]; + [dic setValue:@(keys[1].c_str()) forKey:@"IType"]; + [dic setValue:@(keys[2].c_str()) forKey:@"OType"]; + option.preprocessorMacros = dic; + pipeline = makeComputePipelineWithSourceOption(gCopy, "main0", option); mRuntime->insertPipeline(keys, pipeline); } [encoder setComputePipelineState:pipeline]; - if (shape == nil) { - shape = getConstBuffer(4 * sizeof(int)); - } ((uint32_t*)[shape contents])[0] = size; setTensor(src, encoder, 0); setTensor(dst, encoder, 1); [encoder setBuffer:shape offset:0 atIndex:2]; [encoder dispatchThreadgroups:MTLSizeMake(UP_DIV(size, 256), 1, 1) threadsPerThreadgroup:MTLSizeMake(256, 1, 1)]; } - // convert - else { - auto kernel = kernelForConvert(src->getType(), sfmt, dfmt, None); - MNN_ASSERT(kernel != nil); // unsupported sfmt to dfmt - if (shape == nil) { - shape = getConstBuffer(4 * sizeof(int)); + else if (sfmt == MNN_DATA_FORMAT_NC4HW4 || dfmt == MNN_DATA_FORMAT_NC4HW4) { + auto srcType = _getType(src->getType(), sfmt, mUseFloatAsFp16 && castType != 1); + auto dstType = _getType(dst->getType(), dfmt, mUseFloatAsFp16 && castType != 2); + auto normalTensor = dst; + if (dfmt == MNN_DATA_FORMAT_NC4HW4) { + normalTensor = src; + } + // convert C4 / NCHW + std::vector keys = { + "c4convert", + srcType, + dstType + }; + if (dfmt == MNN_DATA_FORMAT_NC4HW4) { + keys.emplace_back("outputc4"); + } + id pipeline = mRuntime->findPipeline(keys); + if (nil == pipeline) { + MTLCompileOptions *option = [[MTLCompileOptions alloc] init]; + auto dic = [NSMutableDictionary dictionaryWithCapacity:0]; + [dic setValue:@(keys[1].c_str()) forKey:@"IType"]; + [dic setValue:@(keys[2].c_str()) forKey:@"OType"]; + if (dfmt == MNN_DATA_FORMAT_NC4HW4) { + [dic setValue:@"1" forKey:@"MNN_OUTPUT_C4"]; + } + option.preprocessorMacros = dic; + pipeline = makeComputePipelineWithSourceOption(gNC4HW4Convert, "main0", option); + mRuntime->insertPipeline(keys, pipeline); } - - auto size = getTensorShape(shape, src); - auto pipeline = [ctx pipelineWithName:kernel fp16:mUseFloatAsFp16]; [encoder setComputePipelineState:pipeline]; - [encoder setBuffer:( id)((MetalRuntimeAllocator::MetalBufferAlloc *)(src->buffer().device))->getBuffer() offset:TensorUtils::getDescribe(src)->extra.offset atIndex:0]; - [encoder setBuffer:( id)((MetalRuntimeAllocator::MetalBufferAlloc *)(dst->buffer().device))->getBuffer() offset:TensorUtils::getDescribe(dst)->extra.offset atIndex:1]; + auto size = getTensorShape(shape, normalTensor); + MetalBackend::setTensor(src, encoder, 0); + MetalBackend::setTensor(dst, encoder, 1); [encoder setBuffer:shape offset:0 atIndex:2]; auto gl = [ctx computeBestGroupAndLocal:pipeline threads:size]; [encoder dispatchThreadgroups:gl.first threadsPerThreadgroup:gl.second]; + } else { + // NCHW <-> NHWC + auto srcType = _getType(src->getType(), sfmt, mUseFloatAsFp16 && castType != 1); + auto dstType = _getType(dst->getType(), dfmt, mUseFloatAsFp16 && castType != 2); + std::vector keys = { + "transpose", + srcType, + dstType + }; + id pipeline = mRuntime->findPipeline(keys); + if (nil == pipeline) { + MTLCompileOptions *option = [[MTLCompileOptions alloc] init]; + auto dic = [NSMutableDictionary dictionaryWithCapacity:0]; + [dic setValue:@(keys[1].c_str()) forKey:@"IType"]; + [dic setValue:@(keys[2].c_str()) forKey:@"OType"]; + option.preprocessorMacros = dic; + pipeline = makeComputePipelineWithSourceOption(gTranspose, "main0", option); + mRuntime->insertPipeline(keys, pipeline); + } + [encoder setComputePipelineState:pipeline]; + int n, c, plane; + _getNCPlane(dst, plane, c, n); + auto shapePtr = (uint32_t*)shape.contents; + shapePtr[0] = n; + shapePtr[3] = 1; + if (MNN_DATA_FORMAT_NHWC == dfmt) { + shapePtr[1] = plane; + shapePtr[2] = c; + } else { + shapePtr[1] = c; + shapePtr[2] = plane; + } + auto size = plane * n * c; + setTensor(src, encoder, 0); + setTensor(dst, encoder, 1); + [encoder setBuffer:shape offset:0 atIndex:2]; + [encoder dispatchThreadgroups:MTLSizeMake(UP_DIV(size, 256), 1, 1) threadsPerThreadgroup:MTLSizeMake(256, 1, 1)]; } if (standalone) { @@ -690,15 +709,58 @@ kernel void main0(const device int4 *in [[buffer(0)]], device int4 *out [[buffer if (!src->buffer().host && !dst->buffer().host) { onCopyDeviceToDevice(src, dst, encoder, shape); - } else if (!src->buffer().host && dst->buffer().host) { - onCopyDeviceToHost(src, dst); + return; + } + auto sfmt = TensorUtils::getDescribe(src)->dimensionFormat; + auto dfmt = TensorUtils::getDescribe(dst)->dimensionFormat; + bool formatDiff = sfmt != dfmt && src->dimensions() > 1; + auto floats = src->getType().code == halide_type_float; + bool dataTypeDiff = floats && mUseFloatAsFp16; + bool needConvert = formatDiff || dataTypeDiff; + + if (!src->buffer().host && dst->buffer().host) { + auto device = (id)((MetalRuntimeAllocator::MetalBufferAlloc *)src->deviceId())->getBuffer(); + auto devicePtr = (uint8_t*)device.contents + TensorUtils::getDescribe(src)->extra.offset; + if (needConvert) { + auto tDst = const_cast(dst); + auto tmpBuffer = getHostBuffer(dst->usize()); + MetalRuntimeAllocator::MetalBufferAlloc tmp(tmpBuffer); + TensorUtils::getDescribe(tDst)->extra.offset = 0; + tDst->buffer().device = (uint64_t)(&tmp); + onCopyDeviceToDevice(src, dst, nullptr, nullptr, 2); + tDst->buffer().device = 0; + devicePtr = (uint8_t*)tmpBuffer.contents; + commit(); + } + wait(); + ::memcpy(dst->host(), devicePtr, dst->usize()); + return; + } + if (src->buffer().host && !dst->buffer().host) { + auto device = (id)((MetalRuntimeAllocator::MetalBufferAlloc *)dst->deviceId())->getBuffer(); + auto devicePtr = (uint8_t*)device.contents + TensorUtils::getDescribe(dst)->extra.offset; - } else if (src->buffer().host && !dst->buffer().host) { - onCopyHostToDevice(src, dst); - - } else { - MNN_ASSERT(false); // should not be handled here + // For command queue from user, need user to make sure last frame's gpu work is ready + bool needWait = !mRuntime->userSync(); + if (needWait) { + wait(); + } + auto srcSize = src->usize(); + if (needConvert) { + auto tmpBuffer = getHostBuffer(srcSize); + ::memcpy(tmpBuffer.contents, src->host(), srcSize); + MetalRuntimeAllocator::MetalBufferAlloc tmp(tmpBuffer); + auto tSrc = const_cast(src); + TensorUtils::getDescribe(tSrc)->extra.offset = 0; + tSrc->buffer().device = (uint64_t)(&tmp); + onCopyDeviceToDevice(tSrc, dst, nullptr, nullptr, 1); + tSrc->buffer().device = 0; + } else { + ::memcpy(devicePtr, src->host(), srcSize); + } + return; } + MNN_ASSERT(false); // should not be handled here } int MetalBackend::onSync(Tensor::MapType mtype, bool toCpu, const Tensor* dstTensor) { flushEncoder(); diff --git a/source/backend/metal/ShaderMap.cpp b/source/backend/metal/ShaderMap.cpp index 0b6b74780..bcdbe5e88 100644 --- a/source/backend/metal/ShaderMap.cpp +++ b/source/backend/metal/ShaderMap.cpp @@ -7,7 +7,6 @@ mMaps.insert(std::make_pair("shader_MetalConvolutionDepthwise_metal", shader_Met mMaps.insert(std::make_pair("shader_MetalConvolutionActivation_metal", shader_MetalConvolutionActivation_metal)); mMaps.insert(std::make_pair("shader_MetalConvolution_metal", shader_MetalConvolution_metal)); mMaps.insert(std::make_pair("shader_MetalReduction_metal", shader_MetalReduction_metal)); -mMaps.insert(std::make_pair("shader_MetalBackend_metal", shader_MetalBackend_metal)); mMaps.insert(std::make_pair("shader_MetalSoftmax_metal", shader_MetalSoftmax_metal)); mMaps.insert(std::make_pair("shader_MetalLayerNorm_metal", shader_MetalLayerNorm_metal)); mMaps.insert(std::make_pair("shader_MetalConvolutionWinograd_metal", shader_MetalConvolutionWinograd_metal)); diff --git a/source/backend/metal/shader/MetalBackend.metal b/source/backend/metal/shader/MetalBackend.metal deleted file mode 100644 index 973f50fc4..000000000 --- a/source/backend/metal/shader/MetalBackend.metal +++ /dev/null @@ -1,235 +0,0 @@ -struct tensor_shape { - int size; - int channel; - int batch; - int batch_slices; -}; - -struct Limit { - uint4 size; -}; -kernel void upcast_float4(const device ftype4 *in [[buffer(0)]], - device float4 *out [[buffer(1)]], - constant Limit& limit [[buffer(2)]], - uint gid [[thread_position_in_grid]]) { - if (gid < limit.size.x) { - out[int(gid)] = float4(in[int(gid)]); - } -} -kernel void downcast_float4(const device float4 *in [[buffer(0)]], - device ftype4 *out [[buffer(1)]], - constant Limit& limit [[buffer(2)]], - uint gid [[thread_position_in_grid]]) { - if (gid < limit.size.x) { - out[int(gid)] = ftype4(in[int(gid)]); - } -} - -template -static inline void template_NHWC_to_NC4HW4(const device IType *in, device OType *out, constant tensor_shape &s, uint2 gid) { - int b = gid.y % s.batch; - int z = gid.y / s.batch; - int c = z * 4; - - auto off_in = in + b * s.size * s.channel + int(gid.x) * s.channel + c; - auto off_out = out + int(gid.y) * s.size + int(gid.x); - off_out[0] = OType(c + 0 < s.channel ? off_in[0] : 0, - c + 1 < s.channel ? off_in[1] : 0, - c + 2 < s.channel ? off_in[2] : 0, - c + 3 < s.channel ? off_in[3] : 0); -} -kernel void upcast_f_NHWC_to_NC4HW4(const device ftype *in [[buffer(0)]], - device float4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NHWC_to_NC4HW4(in, out, s, gid); -} -kernel void downcast_f_NHWC_to_NC4HW4(const device float *in [[buffer(0)]], - device ftype4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NHWC_to_NC4HW4(in, out, s, gid); -} -kernel void cvt_u_NHWC_to_NC4HW4(const device uchar *in [[buffer(0)]], - device uchar4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NHWC_to_NC4HW4(in, out, s, gid); -} -kernel void cvt_f_NHWC_to_NC4HW4(const device ftype *in [[buffer(0)]], - device ftype4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NHWC_to_NC4HW4(in, out, s, gid); -} - -template -static inline void template_NC4HW4_to_NHWC(const device IType *in, device OType *out, constant tensor_shape &s, uint2 gid) { - int b = gid.y % s.batch; - int z = gid.y / s.batch; - int c = z * 4; - auto off_in = in + int(gid.y) * s.size + int(gid.x); - auto off_out = out + b * s.size * s.channel + int(gid.x) * s.channel + c; - - IType v4 = off_in[0]; - /* if (1) */ off_out[0] = v4[0]; - if (c + 1 < s.channel) off_out[1] = v4[1]; - if (c + 2 < s.channel) off_out[2] = v4[2]; - if (c + 3 < s.channel) off_out[3] = v4[3]; -} -kernel void upcast_f_NC4HW4_to_NHWC(const device ftype4 *in [[buffer(0)]], - device float *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NHWC(in, out, s, gid); -} -kernel void downcast_f_NC4HW4_to_NHWC(const device float4 *in [[buffer(0)]], - device ftype *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NHWC(in, out, s, gid); -} -kernel void cvt_u_NC4HW4_to_NHWC(const device uchar4 *in [[buffer(0)]], - device uchar *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NHWC(in, out, s, gid); -} -kernel void cvt_f_NC4HW4_to_NHWC(const device ftype4 *in [[buffer(0)]], - device ftype *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NHWC(in, out, s, gid); -} - -template -static inline void template_NCHW_to_NC4HW4(const device IType *in, device OType *out, constant tensor_shape &s, uint2 gid) { - int b = gid.y % s.batch; - int z = gid.y / s.batch; - int c = z * 4; - - auto off_in = in + (b * s.channel + c) * s.size + int(gid.x); - auto off_out = out + int(gid.y) * s.size + int(gid.x); - off_out[0] = OType(c + 0 < s.channel ? off_in[0 * s.size] : 0.0h, - c + 1 < s.channel ? off_in[1 * s.size] : 0.0h, - c + 2 < s.channel ? off_in[2 * s.size] : 0.0h, - c + 3 < s.channel ? off_in[3 * s.size] : 0.0h); -} -kernel void upcast_f_NCHW_to_NC4HW4(const device ftype *in [[buffer(0)]], - device float4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NCHW_to_NC4HW4(in, out, s, gid); -} -kernel void downcast_f_NCHW_to_NC4HW4(const device float *in [[buffer(0)]], - device ftype4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NCHW_to_NC4HW4(in, out, s, gid); -} -kernel void cvt_u_NCHW_to_NC4HW4(const device uchar *in [[buffer(0)]], - device uchar4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NCHW_to_NC4HW4(in, out, s, gid); -} -kernel void cvt_f_NCHW_to_NC4HW4(const device ftype *in [[buffer(0)]], - device ftype4 *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NCHW_to_NC4HW4(in, out, s, gid); -} - -template -static inline void template_NC4HW4_to_NCHW(const device IType *in, device OType *out, constant tensor_shape &s, uint2 gid) { - int b = gid.y % s.batch; - int z = gid.y / s.batch; - int c = z * 4; - - auto off_in = in + int(gid.y) * s.size + int(gid.x); - auto off_out = out + (b * s.channel + c) * s.size + int(gid.x); - IType v4 = off_in[0]; - /* if (1) */ off_out[0 * s.size] = v4.x; - if (c + 1 < s.channel) off_out[1 * s.size] = v4.y; - if (c + 2 < s.channel) off_out[2 * s.size] = v4.z; - if (c + 3 < s.channel) off_out[3 * s.size] = v4.w; -} -kernel void upcast_f_NC4HW4_to_NCHW(const device ftype4 *in [[buffer(0)]], - device float *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NCHW(in, out, s, gid); -} -kernel void downcast_f_NC4HW4_to_NCHW(const device float4 *in [[buffer(0)]], - device ftype *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NCHW(in, out, s, gid); -} -kernel void cvt_u_NC4HW4_to_NCHW(const device uchar4 *in [[buffer(0)]], - device uchar *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NCHW(in, out, s, gid); -} -kernel void cvt_f_NC4HW4_to_NCHW(const device ftype4 *in [[buffer(0)]], - device ftype *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NC4HW4_to_NCHW(in, out, s, gid); -} - -template -static inline void template_NHWC_to_NCHW(const device IType* in, - device OType* out, constant tensor_shape &s, uint2 gid) { - int b = gid.y % s.batch; - int c4 = gid.y / s.batch; - - auto in_off = (b * s.size + gid.x) * s.channel + c4 * 4; - auto out_off = (b * s.channel + c4 * 4) * s.size + gid.x; - - out[out_off] = in[in_off]; - if(c4 * 4 + 1 < s.channel) { - out[out_off + s.size] = in[in_off + 1]; - } - if(c4 * 4 + 2 < s.channel) { - out[out_off + s.size * 2] = in[in_off + 2]; - } - if(c4 * 4 + 3 < s.channel) { - out[out_off + s.size * 3] = in[in_off + 3]; - } -} - -kernel void upcast_f_NHWC_to_NCHW(const device ftype *in [[buffer(0)]], - device float *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NHWC_to_NCHW(in, out, s, gid); -} - -template -static inline void template_NCHW_to_NHWC(const device IType* in, - device OType* out, constant tensor_shape &s, uint2 gid) { - int b = gid.y % s.batch; - int c4 = gid.y / s.batch; - - auto in_off = (b * s.channel + c4 * 4) * s.size + gid.x; - auto out_off = (b * s.size + gid.x) * s.channel + c4 * 4; - - out[out_off] = in[in_off]; - if(c4 * 4 + 1 < s.channel) { - out[out_off + 1] = in[in_off + s.size]; - } - if(c4 * 4 + 2 < s.channel) { - out[out_off + 2] = in[in_off + s.size * 2]; - } - if(c4 * 4 + 3 < s.channel) { - out[out_off + 3] = in[in_off + s.size * 3]; - } -} -kernel void downcast_f_NCHW_to_NHWC(const device float *in [[buffer(0)]], - device ftype *out [[buffer(1)]], - constant tensor_shape &s [[buffer(2)]], - uint2 gid [[thread_position_in_grid]]) { - if ((int)gid.x < s.size && (int)gid.y < s.batch_slices) template_NCHW_to_NHWC(in, out, s, gid); -} diff --git a/source/backend/opencl/core/BufferConvertor.cpp b/source/backend/opencl/core/BufferConvertor.cpp index ab51ef7db..1d649a0b8 100644 --- a/source/backend/opencl/core/BufferConvertor.cpp +++ b/source/backend/opencl/core/BufferConvertor.cpp @@ -405,6 +405,7 @@ bool BufferConvertor::convertToNC4HW4Buffer(const Tensor *buffer, const OpenCLBu auto runtime = mOpenCLRuntime; std::string kernelName; + std::string kernelFile = "buffer_convert_buf"; switch (type) { case CONV2D_FILTER: #ifdef MNN_LOW_MEMORY @@ -413,6 +414,7 @@ bool BufferConvertor::convertToNC4HW4Buffer(const Tensor *buffer, const OpenCLBu MNN_ERROR("For Opencl Backend, only support low memory mode of int8 or int4 dequantization currently.\n"); MNN_ASSERT(false); } + kernelFile = "buffer_convert_quant"; // shared part for all cases if (quantBit == 8) { kernelName = "conv2d_filter_buffer_to_nc4hw4_buffer_int8"; //NC4HW4 (1, 4*ic/4, kw*kh*oc/4, 1)*4 @@ -452,7 +454,7 @@ bool BufferConvertor::convertToNC4HW4Buffer(const Tensor *buffer, const OpenCLBu } else {/* More types to be supported. */} } #endif - mBufferToImageKernel = runtime->buildKernelWithCache("buffer_convert_buf", kernelName, buildOptions, buffer, image); + mBufferToImageKernel = runtime->buildKernelWithCache(kernelFile, kernelName, buildOptions, buffer, image); } auto kernel = mBufferToImageKernel->get(); diff --git a/source/backend/opencl/core/OpenCLGemmTune.cpp b/source/backend/opencl/core/OpenCLGemmTune.cpp new file mode 100644 index 000000000..870bf7530 --- /dev/null +++ b/source/backend/opencl/core/OpenCLGemmTune.cpp @@ -0,0 +1,417 @@ +// +// OpenCLGemmTune.cpp +// MNN +// +// Created by MNN on 2024/05/30. +// Copyright © 2018, Alibaba Group Holding Limited +// + +#include "backend/opencl/core/OpenCLRunningUtils.hpp" +#include +#include +#include +#include +#include "core/Macro.h" + +namespace MNN { +namespace OpenCL { + + +static void generateCombinations(const std::vector> &candidates, std::vector ¤tCombination, std::vector> &totalCombinations, int depth) { + if (depth == candidates.size()) { + totalCombinations.emplace_back(currentCombination); + return; + } + + // Loop all candidates + for (int i = 0; i < candidates[depth].size(); i++) { + currentCombination[depth] = candidates[depth][i]; + // Recurrence + generateCombinations(candidates, currentCombination, totalCombinations, depth + 1); + } +} + + +static bool isCandidateValid(uint32_t kwg, uint32_t kwi, uint32_t mwg, uint32_t mdimc, uint32_t vwm, uint32_t nwg, uint32_t ndimc, uint32_t vwn, uint32_t mdima, uint32_t ndimb, uint32_t sa, uint32_t sb, OpenCLRuntime *runtime, const std::vector& gemmSize) { + // problem size align + if(gemmSize[0] % mwg != 0 || gemmSize[1] % nwg != 0 || gemmSize[2] % kwg != 0) { + return false; + } + // mwg nwg only for M N equal to 16 + if((gemmSize[0] > 16 && mwg == 16) || (gemmSize[1] > 16 && nwg == 16)) { + return false; + } + // params align + if(kwg % kwi != 0) { + return false; + } + if(mwg % (mdimc * vwm) != 0 || mwg % (mdima * vwm) != 0) { + return false; + } + if(nwg % (ndimc * vwn) != 0 || nwg % (ndimb * vwn) != 0) { + return false; + } + uint32_t kdima = (mdimc * ndimc) / mdima; + uint32_t kdimb = (mdimc * ndimc) / ndimb; + if(kwg % kdima != 0 || kwg % kdimb != 0) { + return false; + } + if(mdimc != mdima || ndimc != ndimb) { + return false; + } + if(sa != sb) { + return false; + } + + // local memory limit + uint32_t local_mem_size = 0; + if(sa) { + local_mem_size += kwg * mwg; + } + if(sb) { + local_mem_size += kwg * nwg; + } + if(runtime->isSupportedFP16()) { + local_mem_size *= 2; + } else { + local_mem_size *= 4; + } + if(local_mem_size > runtime->getMaxLocalMem()) { + return false; + } + + // local size limit + if(mdimc * ndimc > runtime->MaxWorkGroupSize()) { + return false; + } + + // reduce total candidate number + if(mdimc != mdima || ndimc != ndimb) { + return false; + } + bool totalLarge = 1.0 * gemmSize[0] / 1024 * gemmSize[1] / 1024 * gemmSize[2] / 1024 >= 0.5; + bool dimLarge = gemmSize[0] > 128 && gemmSize[1] > 128 && gemmSize[2] > 128; + if(totalLarge && dimLarge) { + if(mwg * nwg < 128 * 64) { + return false; + } + if(mdimc * ndimc < 16 * 8) { + return false; + } + if(vwm * vwn < 4 * 4) { + return false; + } + } else { + if(mwg * nwg > 128 * 64) { + return false; + } + if(mdimc * ndimc > 16 * 8) { + return false; + } + if(vwm * vwn > 4 * 4) { + return false; + } + } + + return true; +} + +std::vector getGemmParams(const std::vector &gemmSize, const std::vector tensorMemory, + OpenCLRuntime *runtime) { + MNN_ASSERT(gemmSize.size() == 5); // M, N, K, Layout, B + MNN_ASSERT(gemmSize[0] % 16 == 0); + MNN_ASSERT(gemmSize[1] % 16 == 0); + MNN_ASSERT(gemmSize[2] % 16 == 0); + + MNN_ASSERT(tensorMemory.size() == 3); + auto& tunedGemmParams = runtime->tunedGemmParamsMap(); + + + std::vector info(gemmSize); + uint32_t isFp16 = runtime->isSupportedFP16(); + info.emplace_back(isFp16); + + if (tunedGemmParams.find(info) != tunedGemmParams.end()) { + return tunedGemmParams[info]; + } + + if(runtime->getCLTuneLevel() == None) { + auto getMaxDivisor = [](uint32_t num) -> uint32_t { + std::vector divisors = {128, 64, 32}; + for (const auto& divisor : divisors) { + if (num % divisor == 0) { + return divisor; + } + } + return 16; + }; + float multiNum = 1.0 * gemmSize[0] / 512.0 * gemmSize[1] / 512.0 * gemmSize[2] / 512.0; + int maxDivsorM = getMaxDivisor(gemmSize[0]); + int maxDivsorN = getMaxDivisor(gemmSize[1]); + + if(gemmSize[4] == 1) {// Gemm + if(gemmSize[0] >= 256 && gemmSize[1] >= 256 && gemmSize[2] >= 256) { + if(multiNum > 8.0) { + if(maxDivsorM >= 128 && maxDivsorN >= 64) { + return {0, 1, 16, 2, 16, 16, 128, 8, 8, 64, 0, 0, 0, 1, 8, 8}; + } + } + if(maxDivsorM >= 64 && maxDivsorN >= 64) { + return {0, 1, 16, 2, 8, 8, 64, 8, 8, 64, 0, 0, 0, 1, 8, 8}; + } + } + } else {// BatchGemm + if(maxDivsorM >= 64 && maxDivsorN >= 128) { + return {0, 1, 16, 2, 16, 16, 64, 8, 8, 128, 0, 0, 1, 0, 2, 8}; + } else if(maxDivsorM >= 64 && maxDivsorN >= 64) { + return {0, 1, 16, 2, 8, 8, 64, 8, 8, 64, 0, 0, 1, 0, 4, 4}; + } + } + return {0, 1, 16, 2, 4, 4, 16, 4, 4, 16, 0, 0, 1, 0, 2, 2}; + } + + std::vector> totalCombinations; // save total candidate combinations + std::vector params_prefer = {0, 1, 16, 2, 4, 4, 16, 4, 4, 16, 0, 0, 1, 0, 2, 2}; + totalCombinations.emplace_back(params_prefer); + uint32_t min_cost = UINT_MAX; + + if(runtime->getCLTuneLevel() >= Normal) { + // set candidates + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 64 , 8 , 8 , 128, 0, 0, 1, 1, 2, 8});//12 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 0, 0, 8, 8});//11 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 0, 8, 8});//4 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 1, 2, 8});//2 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 128, 0, 0, 0, 1, 8, 8}); + totalCombinations.push_back({0, 1, 16, 2, 8 , 8 , 16 , 8 , 8 , 128, 0, 0, 0, 0, 2, 8}); + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 64 , 8 , 8 , 32 , 0, 0, 0, 0, 4, 4}); + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 32 , 0, 0, 1, 0, 4, 4});//1 + totalCombinations.push_back({0, 1, 16, 2, 8, 8 , 32 , 8 , 8 , 128, 0, 0, 1, 0, 2, 8});//2 + + if(runtime->getCLTuneLevel() == Normal) { + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 64 , 8 , 8 , 128, 0, 0, 1, 1, 2, 8});//10 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 0, 0, 8, 8});//6 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 0, 1, 8, 8});//6 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 0, 2, 8});//4 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 1, 8, 8});//4 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 0, 1, 8, 8});//4 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 0, 2, 8});//3 + totalCombinations.push_back({0, 1, 16, 2, 8, 8 , 64 , 8 , 8 , 64 , 0, 0, 1, 0, 2, 8});//1 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 1, 4, 4});//1 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 0, 8, 8});//2 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 64 , 8 , 8 , 128, 0, 0, 1, 0, 2, 8});//3 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 32 , 0, 0, 1, 1, 4, 4});//1 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 32 , 0, 0, 1, 1, 4, 4});//1 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 16, 16, 128, 0, 0, 0, 0, 8, 8});//1 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 16, 16, 128, 0, 0, 0, 0, 8, 8});//2 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 16, 16, 128, 0, 0, 0, 1, 8, 8});//2 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 1, 8, 8});//2 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 16, 16, 128, 0, 0, 1, 0, 8, 8});//1 + totalCombinations.push_back({0, 1, 32, 2, 8 , 8 , 16 , 8 , 8 , 128, 0, 0, 1, 0, 2, 8});//1 + totalCombinations.push_back({0, 1, 32, 2, 8 , 8 , 16 , 8 , 8 , 128, 0, 0, 1, 1, 2, 8});//1 + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 64 , 8 , 8 , 32 , 0, 0, 0, 1, 4, 4});//1 + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 64 , 8 , 8 , 32 , 0, 0, 0, 1, 4, 4}); + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 64 , 8 , 8 , 32 , 0, 0, 1, 0, 4, 4}); + totalCombinations.push_back({0, 1, 16, 2, 8 , 8 , 16 , 8 , 8 , 128, 0, 0, 1, 0, 2, 8}); + totalCombinations.push_back({0, 1, 32, 2, 8 , 8 , 16 , 8 , 8 , 128, 0, 0, 0, 0, 2, 8}); + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 1, 2, 8}); + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 64 , 0, 0, 1, 0, 4, 8}); + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 8 , 8 , 128, 0, 0, 0, 0, 8, 8}); + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 128, 0, 0, 0, 1, 8, 8}); + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 128, 0, 0, 0, 0, 8, 8}); + totalCombinations.push_back({0, 1, 32, 2, 16, 16, 128, 8 , 8 , 128, 0, 0, 1, 1, 8, 8}); + totalCombinations.push_back({0, 1, 16, 2, 16, 16, 128, 16, 16, 128, 0, 0, 1, 0, 8, 8}); + } + } else { + // get all combinations + std::vector> candidates = { + {0}, // GEMMK + {16, 32, 64, 128}, // MWG + {16, 32, 64, 128}, // NWG + {16, 32}, // KWG + {8, 16}, // MDIMC + {8, 16}, // NDIMC + {8, 16}, // MDIMA + {8, 16}, // NDIMB + {2}, // KWI + {2, 4, 8}, // VWM + {2, 4, 8}, // VWN + {0, 1}, // STRM + {0, 1}, // STRN + {0}, // SA + {0}, // SB + {1} // KREG + }; + + std::vector currentCombination(candidates.size()); + generateCombinations(candidates, currentCombination, totalCombinations, 0); + } + + for(int i = 0; i < totalCombinations.size(); i++) { + uint32_t gemmk = totalCombinations[i][0]; + uint32_t kreg = totalCombinations[i][1]; + uint32_t kwg = totalCombinations[i][2]; + uint32_t kwi = totalCombinations[i][3]; + uint32_t mdima = totalCombinations[i][4]; + uint32_t mdimc = totalCombinations[i][5]; + uint32_t mwg = totalCombinations[i][6]; + uint32_t ndimb = totalCombinations[i][7]; + uint32_t ndimc = totalCombinations[i][8]; + uint32_t nwg = totalCombinations[i][9]; + uint32_t sa = totalCombinations[i][10]; + uint32_t sb = totalCombinations[i][11]; + uint32_t strm = totalCombinations[i][12]; + uint32_t strn = totalCombinations[i][13]; + uint32_t vwm = totalCombinations[i][14]; + uint32_t vwn = totalCombinations[i][15]; + + if(isCandidateValid(kwg, kwi, mwg, mdimc, vwm, nwg, ndimc, vwn, mdima, ndimb, sa, sb, runtime, gemmSize)) { + + std::set buildOptions; + buildOptions.clear(); + buildOptions.emplace("-DGEMMK=" + std::to_string(gemmk)); + buildOptions.emplace("-DKREG=" + std::to_string(kreg)); + buildOptions.emplace("-DKWG=" + std::to_string(kwg)); + buildOptions.emplace("-DKWI=" + std::to_string(kwi)); + buildOptions.emplace("-DMDIMA=" + std::to_string(mdima)); + buildOptions.emplace("-DMDIMC=" + std::to_string(mdimc)); + buildOptions.emplace("-DMWG=" + std::to_string(mwg)); + buildOptions.emplace("-DNDIMB=" + std::to_string(ndimb)); + buildOptions.emplace("-DNDIMC=" + std::to_string(ndimc)); + buildOptions.emplace("-DNWG=" + std::to_string(nwg)); + buildOptions.emplace("-DSA=" + std::to_string(sa)); + buildOptions.emplace("-DSB=" + std::to_string(sb)); + buildOptions.emplace("-DSTRM=" + std::to_string(strm)); + buildOptions.emplace("-DSTRN=" + std::to_string(strn)); + buildOptions.emplace("-DVWM=" + std::to_string(vwm)); + buildOptions.emplace("-DVWN=" + std::to_string(vwn)); + + if(gemmSize[3] >= 4) { + buildOptions.emplace(" -DOUTPUTMN"); + } + if(runtime->getGpuType() == GpuType::ADRENO) { + buildOptions.emplace(" -DUSE_CL_MAD=1"); + buildOptions.emplace(" -DRELAX_WORKGROUP_SIZE=1"); + } + + if(runtime->isSupportedFP16()){ + buildOptions.emplace(" -DPRECISION=16"); + } else { + buildOptions.emplace(" -DPRECISION=32"); + } + + int localM = mdimc; + int localN = ndimc; + + std::shared_ptr kernel = runtime->buildKernel("matmul_params_buf", "Xgemm", buildOptions); + if(kernel == nullptr) { + continue; + } + if(gemmSize[4] > 1) { + kernel = runtime->buildKernel("matmul_params_buf", "XgemmBatched", buildOptions); + if(kernel == nullptr) { + continue; + } + } + + if(localM * localN > runtime->getMaxWorkGroupSize(kernel)) { + continue; + } + int tileM = mwg; + int tileN = nwg; + int out_per_thread_m = tileM / localM; + int out_per_thread_n = tileN / localN; + + std::vector globalWorkSize = {static_cast(gemmSize[0]/out_per_thread_m), static_cast(gemmSize[1]/out_per_thread_n), gemmSize[4]}; + std::vector localWorkSize = {static_cast(localM), static_cast(localN), 1}; + + float alpha = 1.0; + float beta = 0.0f; + // A: [n, l, e] + // B: [n, l, h] + int offset_a = 0; + int offset_b = 0; + int offset_c = 0; + + cl::Event event; + int idx = 0; + cl_int ret = CL_SUCCESS; + ret |= kernel->get().setArg(idx++, static_cast(gemmSize[0])); + ret |= kernel->get().setArg(idx++, static_cast(gemmSize[1])); + ret |= kernel->get().setArg(idx++, static_cast(gemmSize[2])); + ret |= kernel->get().setArg(idx++, alpha); + ret |= kernel->get().setArg(idx++, beta); + if(gemmSize[4] > 1) { + ret |= kernel->get().setArg(idx++, tensorMemory[0]); + ret |= kernel->get().setArg(idx++, gemmSize[0]); + ret |= kernel->get().setArg(idx++, gemmSize[2]); + ret |= kernel->get().setArg(idx++, tensorMemory[1]); + ret |= kernel->get().setArg(idx++, gemmSize[1]); + ret |= kernel->get().setArg(idx++, gemmSize[2]); + ret |= kernel->get().setArg(idx++, tensorMemory[2]); + ret |= kernel->get().setArg(idx++, gemmSize[0]); + ret |= kernel->get().setArg(idx++, gemmSize[1]); + + MNN_CHECK_CL_SUCCESS(ret, "setArg getGemmParams XgemmBatchhed Kernel"); + + auto res = CL_SUCCESS; + res = runtime->commandQueue().enqueueNDRangeKernel(kernel->get(), cl::NullRange, {globalWorkSize[0], globalWorkSize[1], globalWorkSize[2]}, {localWorkSize[0], localWorkSize[1], localWorkSize[2]}, nullptr, &event); + if (res != CL_SUCCESS) { + MNN_PRINT("XgemmBatched params tune error: %d\n", res); + continue; + } + } else { + ret |= kernel->get().setArg(idx++, tensorMemory[0]); + ret |= kernel->get().setArg(idx++, tensorMemory[1]); + ret |= kernel->get().setArg(idx++, tensorMemory[2]); + ret |= kernel->get().setArg(idx++, offset_a); + ret |= kernel->get().setArg(idx++, offset_b); + ret |= kernel->get().setArg(idx++, offset_c); + + MNN_CHECK_CL_SUCCESS(ret, "setArg getGemmParams Xgemm Kernel"); + + auto res = CL_SUCCESS; + res = runtime->commandQueue().enqueueNDRangeKernel(kernel->get(), cl::NullRange, {globalWorkSize[0], globalWorkSize[1]}, {localWorkSize[0], localWorkSize[1]}, nullptr, &event); + if (res != CL_SUCCESS) { + MNN_PRINT("Xgemm params tune error: %d\n", res); + continue; + } + } + + + int cost_time = (int)runtime->getCostTime(&event); + if(cost_time < min_cost) { + min_cost = cost_time; + params_prefer[0] = gemmk; + params_prefer[1] = kreg; + params_prefer[2] = kwg; + params_prefer[3] = kwi; + params_prefer[4] = mdima; + params_prefer[5] = mdimc; + params_prefer[6] = mwg; + params_prefer[7] = ndimb; + params_prefer[8] = ndimc; + params_prefer[9] = nwg; + params_prefer[10] = sa; + params_prefer[11] = sb; + params_prefer[12] = strm; + params_prefer[13] = strn; + params_prefer[14] = vwm; + params_prefer[15] = vwn; + +// for(auto &iter : params_prefer) { +// MNN_PRINT("%d ", iter); +// } +// MNN_PRINT(": %d us, shape:%d %d %d batch:%d, flops:%f GFLOPS\n", min_cost, gemmSize[0], gemmSize[1], gemmSize[2], gemmSize[4], 2.0 / 1000.0 * gemmSize[0] * gemmSize[1] * gemmSize[2] * gemmSize[4] / min_cost); + } + } + } + + if (tunedGemmParams.find(info) == tunedGemmParams.end()) { + tunedGemmParams.insert(std::make_pair(info, params_prefer)); + } + + return params_prefer; +} + +} // namespace OpenCL +} // namespace MNN diff --git a/source/backend/opencl/core/OpenCLOPRegister.cpp b/source/backend/opencl/core/OpenCLOPRegister.cpp index 538a6963d..9f244d651 100644 --- a/source/backend/opencl/core/OpenCLOPRegister.cpp +++ b/source/backend/opencl/core/OpenCLOPRegister.cpp @@ -61,6 +61,9 @@ extern void ___OpenCLGridSampleCreator__OpType_GridSample__IMAGE__(); #ifdef MNN_SUPPORT_TRANSFORMER_FUSE extern void ___OpenCLAttentionBufCreator__OpType_Attention__BUFFER__(); +extern void ___OpenCLSelfAttentionBufCreator__OpType_FmhaV2__BUFFER__(); +extern void ___OpenCLGroupNormBufCreator__OpType_GroupNorm__BUFFER__(); +extern void ___OpenCLSplitGeluBufCreator__OpType_SplitGeLU__BUFFER__(); #endif void registerOpenCLOps() { ___OpenCLInterp3DBufCreator__OpType_Interp3D__BUFFER__(); @@ -121,6 +124,9 @@ ___OpenCLInterpCreator__OpType_Interp__IMAGE__(); ___OpenCLGridSampleCreator__OpType_GridSample__IMAGE__(); #ifdef MNN_SUPPORT_TRANSFORMER_FUSE ___OpenCLAttentionBufCreator__OpType_Attention__BUFFER__(); +___OpenCLSelfAttentionBufCreator__OpType_FmhaV2__BUFFER__(); +___OpenCLGroupNormBufCreator__OpType_GroupNorm__BUFFER__(); +___OpenCLSplitGeluBufCreator__OpType_SplitGeLU__BUFFER__(); #endif } } diff --git a/source/backend/opencl/core/OpenCLRunningUtils.cpp b/source/backend/opencl/core/OpenCLRunningUtils.cpp index f374b6f73..2ad64aa69 100644 --- a/source/backend/opencl/core/OpenCLRunningUtils.cpp +++ b/source/backend/opencl/core/OpenCLRunningUtils.cpp @@ -95,11 +95,11 @@ std::pair, uint32_t> localWS3DDefault(const std::vectorgetCLTuneLevel() == Wide) { while(lws[2] <= gws[2] || lws[2] <= 6) { @@ -132,22 +132,22 @@ std::pair, uint32_t> localWS3DDefault(const std::vector 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] > 6));//divisible powOfTwo lessThanSix } do { - lws[1]++; + lws[1]<<=1; } while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] > 6));//divisible powOfTwo lessThanSix } do { - lws[2]++; + lws[2]<<=1; } while(((2*gws[2])%lws[2] > 1) && (lws[2] & (lws[2] - 1)) != 0 && (lws[2] <= gws[2]) && (lws[2] > 6));//divisible powOfTwo lessThanSix } } else if(runtime->getCLTuneLevel() == Normal) { - while(lws[2] <= gws[2] && lws[2] <= 6) { + while(lws[2] <= gws[2] && lws[2] <= 8) { lws[1] = 1; while(lws[1] <= gws[1] || lws[1] <= 6) { lws[0] = 1; @@ -177,27 +177,27 @@ std::pair, uint32_t> localWS3DDefault(const std::vector 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] > 6));//divisible powOfTwo lessThanSix } do { - lws[1]++; + lws[1]<<=1; } while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] > 6));//divisible powOfTwo lessThanSix } do { - lws[2]++; + lws[2]<<=1; } while(((2*gws[2])%lws[2] > 1) && (lws[2] & (lws[2] - 1)) != 0 && (lws[2] <= gws[2]) && (lws[2] <= 6));//divisible powOfTwo lessThanSix } } else if(runtime->getCLTuneLevel() == Fast) { - while(lws[2] <= gws[2] && lws[2] <= 6) { + while(lws[2] <= gws[2] && lws[2] <= 8) { lws[1] = 1; - while(lws[1] <= gws[1] && lws[1] <= 6) { + while(lws[1] <= gws[1] && lws[1] <= 8) { lws[0] = 1; - while(lws[0] <= gws[0] && lws[0] <= 6) { - if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[2] <= maxWorkItemSizes[2] && lws[0]*lws[1]*lws[2] <= maxWorkGroupSize) { + while(lws[0] <= gws[0] && lws[0] <= 8) { + if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[2] <= maxWorkItemSizes[2] && lws[0]*lws[1]*lws[2] <= std::min(maxWorkGroupSize, static_cast(64)) && lws[0]*lws[1]*lws[2] >= 16) { cl::Event event; std::vector internalGlobalWS(3, 1); for (size_t i = 0; i < gws.size(); ++i) { @@ -222,17 +222,17 @@ std::pair, uint32_t> localWS3DDefault(const std::vector 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] <= 6));//divisible powOfTwo lessThanSix } do { - lws[1]++; + lws[1]<<=1; } while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] <= 6));//divisible powOfTwo lessThanSix } do { - lws[2]++; + lws[2]<<=1; } while(((2*gws[2])%lws[2] > 1) && (lws[2] & (lws[2] - 1)) != 0 && (lws[2] <= gws[2]) && (lws[2] <= 6));//divisible powOfTwo lessThanSix } @@ -266,7 +266,7 @@ std::pair, uint32_t> localWS3DDefault(const std::vectorgetCLTuneLevel() != None) { - //printf("3dLocalWS %d Insert! gws:%d %d %d, lws:%d %d %d\n", (int)tunedLws.size(), gws[0], gws[1], gws[2], lws_prefer[0], lws_prefer[1], lws_prefer[2]); +// printf("3dLocalWS %d Insert! gws:%d %d %d, lws:%d %d %d\n", (int)tunedLws.size(), gws[0], gws[1], gws[2], lws_prefer[0], lws_prefer[1], lws_prefer[2]); tunedLws.insert(std::make_pair(info, std::make_pair(lws_prefer, min_cost))); } @@ -323,9 +323,9 @@ std::pair, uint32_t> localWS2DDefault(const std::vectorgetCLTuneLevel() == Wide) { while(lws[1] <= gws[1] || lws[1] <= 6) { @@ -355,17 +355,17 @@ std::pair, uint32_t> localWS2DDefault(const std::vector 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] > 6));//divisible powOfTwo lessThanSix } do { - lws[1]++; + lws[1]<<=1; } while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] > 6));//divisible powOfTwo lessThanSix } } else if(runtime->getCLTuneLevel() == Normal) { - while(lws[1] <= gws[1] && lws[1] <= 6) { + while(lws[1] <= gws[1] && lws[1] <= 8) { lws[0] = 1; while(lws[0] <= gws[0] || lws[0] <= 6) { if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[0]*lws[1] <= maxWorkGroupSize) { @@ -392,20 +392,20 @@ std::pair, uint32_t> localWS2DDefault(const std::vector 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] > 6));//divisible powOfTwo lessThanSix } do { - lws[1]++; + lws[1]<<=1; } while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] <= 6));//divisible powOfTwo lessThanSix } } else if(runtime->getCLTuneLevel() == Fast) { - while(lws[1] <= gws[1] && lws[1] <= 6) { + while(lws[1] <= gws[1] && lws[1] <= 8) { lws[0] = 1; - while(lws[0] <= gws[0] && lws[0] <= 6) { - if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[0]*lws[1] <= maxWorkGroupSize) { + while(lws[0] <= gws[0] && lws[0] <= 8) { + if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[0]*lws[1] <= maxWorkGroupSize && lws[0]*lws[1] >= 16) { cl::Event event; std::vector internalGlobalWS(2, 1); for (size_t i = 0; i < gws.size(); ++i) { @@ -429,12 +429,12 @@ std::pair, uint32_t> localWS2DDefault(const std::vector 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] <= 6));//divisible powOfTwo lessThanSix } do { - lws[1]++; + lws[1]<<=1; } while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] <= 6));//divisible powOfTwo lessThanSix } @@ -466,7 +466,7 @@ std::pair, uint32_t> localWS2DDefault(const std::vectorgetCLTuneLevel() != None) { - //printf("2dLocalWS %d Insert! gws:%d %d, lws:%d %d\n", (int)tunedLws.size(), gws[0], gws[1], lws_prefer[0], lws_prefer[1]); +// printf("2dLocalWS %d Insert! gws:%d %d, lws:%d %d\n", (int)tunedLws.size(), gws[0], gws[1], lws_prefer[0], lws_prefer[1]); tunedLws.insert(std::make_pair(info, std::make_pair(lws_prefer, min_cost))); } diff --git a/source/backend/opencl/core/OpenCLRunningUtils.hpp b/source/backend/opencl/core/OpenCLRunningUtils.hpp index eb5090e79..63c3fd7df 100644 --- a/source/backend/opencl/core/OpenCLRunningUtils.hpp +++ b/source/backend/opencl/core/OpenCLRunningUtils.hpp @@ -116,7 +116,8 @@ void runKernel2D(const ::std::shared_ptr &kernel, const std::vector< void runTurnKernelLWS2D(const ::std::shared_ptr &kernel, const std::vector &gws, const std::vector &lws, OpenCLRuntime *runtime); - +std::vector getGemmParams(const std::vector &gemmSize, const std::vector tensorMemory, + OpenCLRuntime *runtime); std::pair, uint32_t> localWS3DDefault(const std::vector &gws, const uint32_t maxWorkGroupSize, OpenCLRuntime *runtime, const std::string &kernelName, const std::shared_ptr &mKernel); diff --git a/source/backend/opencl/core/runtime/OpenCLRuntime.cpp b/source/backend/opencl/core/runtime/OpenCLRuntime.cpp index ee7b149e6..1dde1dcbc 100644 --- a/source/backend/opencl/core/runtime/OpenCLRuntime.cpp +++ b/source/backend/opencl/core/runtime/OpenCLRuntime.cpp @@ -17,10 +17,11 @@ //#define MNN_OPEN_TIME_TRACE #include #include "CLCache_generated.h" +#include "backend/opencl/execution/cl/opencl_source_map.hpp" using namespace CLCache; namespace MNN { -extern const std::map> OpenCLProgramMap; +extern const std::map OpenCLProgramMap; extern std::mutex gCLMutex; bool OpenCLRuntime::getDeviceSupportsExtension(const cl::Device &device, const char *extensionName) { @@ -142,7 +143,6 @@ OpenCLRuntime::OpenCLRuntime(const BackendConfig::PrecisionMode precision, const uint32_t num_threads_per_eu = mFirstGPUDevicePtr->getInfo(); uint32_t maxThreadsPerExecutionUnit = num_threads_per_eu > 0 ? num_threads_per_eu : 7; mMaxThreadsPerDevice = maxThreadsPerExecutionUnit * execution_units_count; - mMaxWorkGroupSize = mFirstGPUDevicePtr->getInfo(); } #endif } @@ -230,6 +230,8 @@ OpenCLRuntime::OpenCLRuntime(const BackendConfig::PrecisionMode precision, const mFirstGPUDevicePtr->getInfo(CL_DEVICE_MAX_COMPUTE_UNITS, &mGPUComputeUnits); mFirstGPUDevicePtr->getInfo(CL_DEVICE_MAX_CLOCK_FREQUENCY, &mMaxFreq); mFirstGPUDevicePtr->getInfo(CL_DEVICE_MAX_MEM_ALLOC_SIZE, &mMaxMemAllocSize); + mFirstGPUDevicePtr->getInfo(CL_DEVICE_LOCAL_MEM_SIZE, &mMaxLocalMemSize); + mMaxWorkGroupSize = mFirstGPUDevicePtr->getInfo(); cl_device_fp_config fpConfig; auto success = mFirstGPUDevicePtr->getInfo(CL_DEVICE_HALF_FP_CONFIG, &fpConfig); mIsDeviceSupportedFP16 = CL_SUCCESS == success && fpConfig > 0; @@ -246,7 +248,6 @@ OpenCLRuntime::OpenCLRuntime(const BackendConfig::PrecisionMode precision, const mMemType = IMAGE; } } - mPrecisionLevel = 1; if (mIsDeviceSupportedFP16) { if (precision == BackendConfig::Precision_Low) { @@ -412,10 +413,14 @@ unsigned int OpenCLRuntime::getQueueNum() { return mQueueCount; } +std::map, std::vector>& OpenCLRuntime::tunedGemmParamsMap() { + return mTunedGemmParams; +} + std::map>, std::pair, uint32_t>>& OpenCLRuntime::tunedLwsMap() { return mTunedLws; } - + std::map, std::pair, uint32_t>>>>& OpenCLRuntime::getTuneLwsMap() { return mTuneLws; } @@ -503,7 +508,7 @@ bool OpenCLRuntime::loadProgram(const std::string &programName, cl::Program *pro auto it_source = OpenCLProgramMap.find(programName); if (it_source != OpenCLProgramMap.end()) { cl::Program::Sources sources; - std::string source(it_source->second.begin(), it_source->second.end()); + std::string source(it_source->second); sources.push_back(source); *program = cl::Program(context(), sources); return true; @@ -605,12 +610,14 @@ std::shared_ptr OpenCLRuntime::buildKernelWithCache(const std::strin buildOptionsStr += " -DOUTPUT_TYPE4=char4"; buildOptionsStr += " -DOUTPUT_TYPE16=char16"; buildOptionsStr += " -DCONVERT_OUTPUT4=convert_char4"; + buildOptionsStr += " -DCONVERT_OUTPUT16=convert_char16"; buildOptionsStr += " -DWI_DATA=write_imagei"; } else if(output->getType().bits == 32){ buildOptionsStr += " -DOUTPUT_TYPE=int"; buildOptionsStr += " -DOUTPUT_TYPE4=int4"; buildOptionsStr += " -DOUTPUT_TYPE16=int16"; buildOptionsStr += " -DCONVERT_OUTPUT4=convert_int4"; + buildOptionsStr += " -DCONVERT_OUTPUT16=convert_int16"; buildOptionsStr += " -DWI_DATA=write_imagei"; } else { MNN_PRINT("opencl input datatype not support, bit:%d\n", output->getType().bits); @@ -625,12 +632,14 @@ std::shared_ptr OpenCLRuntime::buildKernelWithCache(const std::strin buildOptionsStr += " -DOUTPUT_TYPE4=uchar4"; buildOptionsStr += " -DOUTPUT_TYPE16=uchar16"; buildOptionsStr += " -DCONVERT_OUTPUT4=convert_uchar4"; + buildOptionsStr += " -DCONVERT_OUTPUT16=convert_uchar16"; buildOptionsStr += " -DWI_DATA=write_imageui"; } else if(output->getType().bits == 32){ buildOptionsStr += " -DOUTPUT_TYPE=uint"; buildOptionsStr += " -DOUTPUT_TYPE4=uint4"; buildOptionsStr += " -DOUTPUT_TYPE16=uint16"; buildOptionsStr += " -DCONVERT_OUTPUT4=convert_uint4"; + buildOptionsStr += " -DCONVERT_OUTPUT16=convert_uint16"; buildOptionsStr += " -DWI_DATA=write_imageui"; } else { MNN_PRINT("opencl input datatype not support, bit:%d\n", output->getType().bits); @@ -681,6 +690,7 @@ std::shared_ptr OpenCLRuntime::buildKernelWithCache(const std::strin auto status = this->buildProgram(buildOptionsStr, &program); if (!status) { FUNC_PRINT_ALL(programName.c_str(), s); + return nullptr; } ProgramWithKernel pwk; pwk.program = program; @@ -699,7 +709,10 @@ std::shared_ptr OpenCLRuntime::buildKernelWithCache(const std::strin if (kiter->second.recycle.empty()) { cl_int res; kernel.reset(new cl::Kernel(program, kernelName.c_str(), &res)); - MNN_CHECK_CL_SUCCESS(res, "getKernel"); + if(res != CL_SUCCESS) { + MNN_ERROR("getKernel: %s error, res:%d\n", kernelName.c_str(), res); + return nullptr; + } if (firstCreate) { kernel->getWorkGroupInfo(*mFirstGPUDevicePtr, CL_KERNEL_WORK_GROUP_SIZE, &kiter->second.maxWorkGroupSize); } @@ -767,6 +780,9 @@ std::vector OpenCLRuntime::getMaxWorkItemSizes() { return mMaxWorkIterms; } +uint64_t OpenCLRuntime::getMaxLocalMem() const { + return mMaxLocalMemSize; +} double OpenCLRuntime::getCostTime(const cl::Event *event){ //cl_int res = mCommandQueuePtr->finish(); cl_int res = event->wait(); @@ -803,6 +819,18 @@ std::pair OpenCLRuntime::makeCache(void* tuneInfo) { for (auto& iter : mBuildProgramMap) { std::unique_ptr pro(new ShaderT); auto program = iter.second.program; + auto bufferSize = iter.second.BufferSize; + // Only use first one + pro->program = std::get<0>(iter.first); + pro->buildInfo = std::get<1>(iter.first); + + //MNN_PRINT("%s - %s - %s\n", pro->program.c_str(), pro->kernel.c_str(), pro->buildInfo.c_str()); + if(bufferSize != 0){ + pro->buffer.resize(bufferSize); + ::memcpy(pro->buffer.data(), iter.second.Buffer.get(), bufferSize); + cache->programs.emplace_back(std::move(pro)); + continue; + } auto devicesNumber = program.getInfo(); auto devices = program.getInfo(); auto binSizes = program.getInfo(); @@ -810,11 +838,6 @@ std::pair OpenCLRuntime::makeCache(void* tuneInfo) { MNN_ERROR("Can't load binary, binarySize:%lu, deviceSize:%lu\n", binSizes.size(), devices.size()); continue; } - // Only use first one - pro->program = std::get<0>(iter.first); - pro->buildInfo = std::get<1>(iter.first); - - //MNN_PRINT("%s - %s - %s\n", pro->program.c_str(), pro->kernel.c_str(), pro->buildInfo.c_str()); pro->buffer.resize(binSizes[0]); auto proRaw = program.get(); @@ -832,6 +855,14 @@ std::pair OpenCLRuntime::makeCache(void* tuneInfo) { cache->tunings.emplace_back(std::move(tuning)); } + // Get All GemmInfo cache + for (auto& iter : mTunedGemmParams) { + std::unique_ptr tuning(new GemmInfoT); + tuning->gemmSize = iter.first; + tuning->paramInfo = iter.second; + cache->gemm.emplace_back(std::move(tuning)); + } + flatbuffers::FlatBufferBuilder builder; auto lastOffset = Cache::Pack(builder, cache.get()); builder.Finish(lastOffset); @@ -842,17 +873,13 @@ std::pair OpenCLRuntime::makeCache(void* tuneInfo) { bool OpenCLRuntime::setCache(std::pair cache) { if (nullptr == cache.first) { - mCacheOutside = nullptr; - mCacheOutsideSize = 0; mBuffer.clear(); return true; } - - mCacheOutsideSize = cache.second; - mCacheOutside = cache.first; + auto cacheBuffer = GetCache(cache.first); - if(nullptr == cacheBuffer->programs() && nullptr == cacheBuffer->tunings()) { + if(nullptr == cacheBuffer->programs() && nullptr == cacheBuffer->tunings() && nullptr == cacheBuffer->gemm()) { return false; } @@ -885,6 +912,9 @@ bool OpenCLRuntime::setCache(std::pair cache) { } ProgramWithKernel pwk; pwk.program = pro; + pwk.Buffer.reset(new char[bufferSize]); + pwk.BufferSize = bufferSize; + ::memcpy(pwk.Buffer.get(), buffer, bufferSize); mBuildProgramMap.insert(std::make_pair(std::make_tuple(program, buildinfo), pwk)); } } @@ -911,6 +941,29 @@ bool OpenCLRuntime::setCache(std::pair cache) { mTuneLws[tun->key()->str()].push_back(std::make_pair(glo, std::make_pair(loc, cost))); } } + + // Load Gemm Info + if (nullptr != cacheBuffer->gemm()) { + auto tuningInfo = cacheBuffer->gemm(); + for (int i=0; isize(); ++i) { + auto tun = tuningInfo->GetAs(i); + if (nullptr == tun->gemmSize() || nullptr == tun->paramInfo()) { + MNN_ERROR("Error tunning gemm info\n"); + return false; + } + MNN_ASSERT(tun->gemmSize()->size() == 6); + std::vector info(tun->gemmSize()->size()); + for (int v=0; vgemmSize()->data()[v]; + } + MNN_ASSERT(tun->paramInfo()->size() == 16); + std::vector params(tun->paramInfo()->size()); + for (int v=0; vparamInfo()->data()[v]; + } + mTunedGemmParams.insert(std::make_pair(info, params)); + } + } return true; } @@ -920,7 +973,7 @@ void OpenCLRuntime::printEventTime(){ return; } int raster_num = 0, raster_time = 0; - unsigned int conv_time = 0, loop_bg_time = 0, loop_bg_gemm_time = 0; + unsigned int conv_time = 0, loop_bg_time = 0, loop_bg_gemm_time = 0, loop_softmax_time = 0, ori_softmax_time = 0; unsigned int conv_gemm2_buf_time = 0, conv_gemm1_buf_time = 0; unsigned int conv_1x1_buf_time = 0, conv_ori_buf_time = 0, wino_gemm_time = 0; @@ -954,6 +1007,12 @@ void OpenCLRuntime::printEventTime(){ if((mEvents[i].first.length() >= 20 && mEvents[i].first.substr(0, 20) == "While-gemm-batchgemm")) { loop_bg_gemm_time += kernel_time; } + if((mEvents[i].first.length() >= 18 && mEvents[i].first.substr(0, 18) == "While-gemm-softmax")) { + loop_softmax_time += kernel_time; + } + if((mEvents[i].first.length() >= 7 && mEvents[i].first.substr(0, 7) == "Softmax")) { + ori_softmax_time += kernel_time; + } if((mEvents[i].first.length() >= 23 && mEvents[i].first.substr(0, 23) == "Conv-winograd-batchgemm")) { wino_gemm_time += kernel_time; conv_time += kernel_time; @@ -978,7 +1037,7 @@ void OpenCLRuntime::printEventTime(){ MNN_PRINT("kernel time = %d us %s\n", kernels[i].second, kernels[i].first.c_str()); } mEvents.clear(); - MNN_PRINT("total kernel time = %d us, conv time = %d us (gemm2:%d us, gemm1:%d us, 1x1:%d us, ori:%d us, wino: %d us, other: %d us), while gemm time = %d us (core gemm time: %d us)\n", mKernelTime, conv_time, conv_gemm2_buf_time, conv_gemm1_buf_time, conv_1x1_buf_time, conv_ori_buf_time, wino_gemm_time, conv_time-conv_gemm2_buf_time-conv_gemm1_buf_time-conv_1x1_buf_time-conv_ori_buf_time-wino_gemm_time, loop_bg_time, loop_bg_gemm_time); + MNN_PRINT("total kernel time = %d us, conv time = %d us (gemm2:%d us, gemm1:%d us, 1x1:%d us, ori:%d us, wino: %d us, other: %d us), while gemm time = %d us (core gemm time: %d us, softmax:%d us), ori softmax: %d us\n", mKernelTime, conv_time, conv_gemm2_buf_time, conv_gemm1_buf_time, conv_1x1_buf_time, conv_ori_buf_time, wino_gemm_time, conv_time-conv_gemm2_buf_time-conv_gemm1_buf_time-conv_1x1_buf_time-conv_ori_buf_time-wino_gemm_time, loop_bg_time, loop_bg_gemm_time, loop_softmax_time, ori_softmax_time); #endif } } // namespace MNN diff --git a/source/backend/opencl/core/runtime/OpenCLRuntime.hpp b/source/backend/opencl/core/runtime/OpenCLRuntime.hpp index 3e208e806..13f40a6c6 100644 --- a/source/backend/opencl/core/runtime/OpenCLRuntime.hpp +++ b/source/backend/opencl/core/runtime/OpenCLRuntime.hpp @@ -139,6 +139,9 @@ class OpenCLRuntime { unsigned int getQueueNum(); unsigned int mKernelTime = 0; + + + std::map, std::vector>& tunedGemmParamsMap(); std::map>, std::pair, uint32_t>>& tunedLwsMap(); @@ -182,6 +185,8 @@ class OpenCLRuntime { struct ProgramWithKernel { cl::Program program; std::map kernels; + std::shared_ptr Buffer; + int BufferSize = 0; }; cl::CommandQueue* mCurrentCommandQueue; std::map, ProgramWithKernel> mBuildProgramMap; @@ -223,11 +228,10 @@ class OpenCLRuntime { double mStartNanos; double mStopNanos; + std::map, std::vector> mTunedGemmParams; std::map>, std::pair, uint32_t>> mTunedLws; std::map, std::pair, uint32_t>>>> mTuneLws; std::vector mBuffer; - const void* mCacheOutside = nullptr; - size_t mCacheOutsideSize = 0; }; } // namespace MNN diff --git a/source/backend/opencl/execution/buffer/AttentionBufExecution.cpp b/source/backend/opencl/execution/buffer/AttentionBufExecution.cpp index 3ff74740f..2382a7081 100644 --- a/source/backend/opencl/execution/buffer/AttentionBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/AttentionBufExecution.cpp @@ -7,6 +7,7 @@ // #ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE #include "backend/opencl/execution/buffer/AttentionBufExecution.hpp" @@ -25,7 +26,7 @@ void AttentionBufImpl::allocKVCache() { return; } mMaxLength = mPastLength + mExpandChunk; - size_t buffer_size = UP_DIV(mMaxLength, 4) * mNumHead * mHeadDim * 4 * mByte; + size_t buffer_size = UP_DIV(mMaxLength, 4) * mKvNumHead * mHeadDim * 4 * mByte; // past_key: [1, numhead, headdim, maxlen] mPastKey.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size)); // past_value: [1, numhead, maxlen, headdim] @@ -36,9 +37,10 @@ void AttentionBufImpl::reallocKVCache() { if (!mKVCache || mPastLength < mMaxLength) { return; } - size_t old_size = mNumHead * UP_DIV(mMaxLength, 4) * mHeadDim * 4 * mByte; + + size_t old_size = mKvNumHead * UP_DIV(mMaxLength, 4) * mHeadDim * 4 * mByte; mMaxLength = mPastLength + mExpandChunk; - size_t buffer_size = UP_DIV(mMaxLength, 4) * mNumHead * mHeadDim * 4 * mByte; + size_t buffer_size = UP_DIV(mMaxLength, 4) * mKvNumHead * mHeadDim * 4 * mByte; // past_key: [1, numhead, headdim, maxlen] auto new_key = new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size); // past_value: [1, numhead, maxlen, headdim] @@ -69,25 +71,25 @@ void AttentionBufImpl::reallocKVCache() { mPastKey.reset(new_key); mPastValue.reset(new_value); - size_t temp_size = UP_DIV(mMaxLength, 4) * mNumHead * 4 * mByte; - mTempQK.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, temp_size)); - mTempSoftMax.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, temp_size)); - + mTempQK.reset(Tensor::createDevice({UP_DIV(mMaxLength, 4) * mNumHead * 4})); + mTempSoftMax.reset(Tensor::createDevice({UP_DIV(mMaxLength, 4) * mNumHead * 4})); + mOpenCLBackend->onAcquireBuffer(mTempQK.get(), Backend::STATIC); + mOpenCLBackend->onAcquireBuffer(mTempSoftMax.get(), Backend::STATIC); // reset memory for args if(mOpenCLBackend->isUseRecordQueue()){ - mQkUpdateInfo.update_kernel_args[1].arg_value = &(*(mTempQK.get()))(); + mQkUpdateInfo.update_kernel_args[1].arg_value = &openCLBuffer(mTempQK.get())(); mQkUpdateInfo.update_kernel_args[2].arg_value = &(*(mPastKey.get()))(); - mSoftMaxUpdateInfo.update_kernel_args[0].arg_value = &(*(mTempQK.get()))(); - mSoftMaxUpdateInfo.update_kernel_args[1].arg_value = &(*(mTempSoftMax.get()))(); - mQkvUpdateInfo.update_kernel_args[0].arg_value = &(*(mTempSoftMax.get()))(); + mSoftMaxUpdateInfo.update_kernel_args[0].arg_value = &openCLBuffer(mTempQK.get())(); + mSoftMaxUpdateInfo.update_kernel_args[1].arg_value = &openCLBuffer(mTempSoftMax.get())(); + mQkvUpdateInfo.update_kernel_args[0].arg_value = &openCLBuffer(mTempSoftMax.get())(); mQkvUpdateInfo.update_kernel_args[1].arg_value = &(*(mPastValue.get()))(); }else{ cl_int ret = CL_SUCCESS; - ret |= mKernel_qk->get().setArg(5, *mTempQK.get()); + ret |= mKernel_qk->get().setArg(5, openCLBuffer(mTempQK.get())); ret |= mKernel_qk->get().setArg(6, *mPastKey.get()); - ret |= mKernel_softmax->get().setArg(3, *mTempQK.get()); - ret |= mKernel_softmax->get().setArg(4, *mTempSoftMax.get()); - ret |= mKernel_qkv->get().setArg(3, *mTempSoftMax.get()); + ret |= mKernel_softmax->get().setArg(3, openCLBuffer(mTempQK.get())); + ret |= mKernel_softmax->get().setArg(4, openCLBuffer(mTempSoftMax.get())); + ret |= mKernel_qkv->get().setArg(3, openCLBuffer(mTempSoftMax.get())); ret |= mKernel_qkv->get().setArg(6, *mPastValue.get()); MNN_CHECK_CL_SUCCESS(ret, "reset memory arg for AttentionBufExecution"); } @@ -125,6 +127,8 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vectorshape()[2]; + int group_size = mNumHead / mKvNumHead; mHeadDim = shape[3]; mScale = 1.0 / sqrt(mHeadDim); mIsDecode = seq_len == 1; @@ -142,14 +146,14 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vectorgetOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size)); - mTempSoftMax.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size)); + mTempQK.reset(Tensor::createDevice({UP_DIV(mMaxLength, 4) * mNumHead * 4})); + mTempSoftMax.reset(Tensor::createDevice({UP_DIV(mMaxLength, 4) * mNumHead * 4})); } else { - size_t buffer_size = UP_DIV(mPastLength, 4) * mPastLength * mNumHead * 4 * mByte; - mTempQK.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size)); - mTempSoftMax.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size)); + mTempQK.reset(Tensor::createDevice({UP_DIV(mPastLength, 4) * mPastLength * mNumHead * 4})); + mTempSoftMax.reset(Tensor::createDevice({UP_DIV(mPastLength, 4) * mPastLength * mNumHead * 4})); } + mOpenCLBackend->onAcquireBuffer(mTempQK.get(), Backend::DYNAMIC); + mOpenCLBackend->onAcquireBuffer(mTempSoftMax.get(), Backend::DYNAMIC); // query * key -> div -> select { @@ -163,6 +167,7 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vectorgetType() == halide_type_of()){ buildOption.emplace("-DADD_MASK"); } + buildOption.emplace("-DNUMHEAD_GROUP_SIZE=" + std::to_string(group_size)); mKernel_qk = runtime->buildKernel("attention_buf", "matmul_qk_div_mask", buildOption, inputs[0], outputs[0]); mGlobalWorkSizeQk = {static_cast(UP_DIV(seq_len, 4)), static_cast(mNumHead), static_cast(UP_DIV(mKv_seq_len, 4))}; auto maxWorkGroupSize = static_cast(runtime->getMaxWorkGroupSize(mKernel_qk)); @@ -175,13 +180,14 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vectorget().setArg(index++, mGlobalWorkSizeQk2); ret |= mKernel_qk->get().setArg(index++, openCLBuffer(query)); ret |= mKernel_qk->get().setArg(index++, openCLBuffer(key)); - ret |= mKernel_qk->get().setArg(index++, *mTempQK.get()); + ret |= mKernel_qk->get().setArg(index++, openCLBuffer(mTempQK.get())); ret |= mKernel_qk->get().setArg(index++, *mPastKey.get()); ret |= mKernel_qk->get().setArg(index++, openCLBuffer(mask)); ret |= mKernel_qk->get().setArg(index++, mScale); ret |= mKernel_qk->get().setArg(index++, seq_len); ret |= mKernel_qk->get().setArg(index++, mKv_seq_len); ret |= mKernel_qk->get().setArg(index++, mNumHead); + ret |= mKernel_qk->get().setArg(index++, mKvNumHead); ret |= mKernel_qk->get().setArg(index++, mHeadDim); MNN_CHECK_CL_SUCCESS(ret, "setArg matmul_qk_div_mask"); @@ -190,7 +196,7 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vectorget().setArg(index++, mGlobalWorkSizeSoftMax[0]); ret |= mKernel_softmax->get().setArg(index++, mGlobalWorkSizeSoftMax[1]); ret |= mKernel_softmax->get().setArg(index++, mGlobalWorkSizeSoftMax[2]); - ret |= mKernel_softmax->get().setArg(index++, *mTempQK.get()); - ret |= mKernel_softmax->get().setArg(index++, *mTempSoftMax.get()); + ret |= mKernel_softmax->get().setArg(index++, openCLBuffer(mTempQK.get())); + ret |= mKernel_softmax->get().setArg(index++, openCLBuffer(mTempSoftMax.get())); ret |= mKernel_softmax->get().setArg(index++, mSoftMaxRemainChannels); ret |= mKernel_softmax->get().setArg(index++, mSoftmaxShape); MNN_CHECK_CL_SUCCESS(ret, "setArg softmax"); @@ -244,8 +250,8 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vector(runtime->getMaxWorkGroupSize(mKernel_qkv)); mGlobalWorkSizeQkv = {static_cast(UP_DIV(seq_len, 4)), static_cast(mNumHead), static_cast(UP_DIV(mHeadDim, 4))}; @@ -270,13 +277,14 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vectorget().setArg(index++, mGlobalWorkSizeQkv[0]); ret |= mKernel_qkv->get().setArg(index++, mGlobalWorkSizeQkv[1]); ret |= mKernel_qkv->get().setArg(index++, mGlobalWorkSizeQkv[2]); - ret |= mKernel_qkv->get().setArg(index++, *mTempSoftMax.get()); + ret |= mKernel_qkv->get().setArg(index++, openCLBuffer(mTempSoftMax.get())); ret |= mKernel_qkv->get().setArg(index++, openCLBuffer(value)); ret |= mKernel_qkv->get().setArg(index++, openCLBuffer(outputs[0])); ret |= mKernel_qkv->get().setArg(index++, *mPastValue.get()); ret |= mKernel_qkv->get().setArg(index++, seq_len); ret |= mKernel_qkv->get().setArg(index++, mKv_seq_len); ret |= mKernel_qkv->get().setArg(index++, mNumHead); + ret |= mKernel_qkv->get().setArg(index++, mKvNumHead); ret |= mKernel_qkv->get().setArg(index++, mHeadDim); MNN_CHECK_CL_SUCCESS(ret, "setArg matmul_qkv"); @@ -285,7 +293,7 @@ ErrorCode AttentionBufImpl::onResize(Backend *backend, const std::vectorendRecord(mRecording); + + mOpenCLBackend->onReleaseBuffer(mTempQK.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(mTempSoftMax.get(), Backend::DYNAMIC); return NO_ERROR; } @@ -414,5 +425,6 @@ REGISTER_OPENCL_OP_CREATOR(AttentionBufCreator, OpType_Attention, BUFFER); } // namespace OpenCL } // namespace MNN +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ #endif/* MNN_OPENCL_BUFFER_CLOSED */ diff --git a/source/backend/opencl/execution/buffer/AttentionBufExecution.hpp b/source/backend/opencl/execution/buffer/AttentionBufExecution.hpp index 20ee66ec6..9de3796d9 100644 --- a/source/backend/opencl/execution/buffer/AttentionBufExecution.hpp +++ b/source/backend/opencl/execution/buffer/AttentionBufExecution.hpp @@ -7,6 +7,7 @@ // #ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE #ifndef AttentionBufExecution_hpp #define AttentionBufExecution_hpp @@ -36,12 +37,13 @@ class AttentionBufImpl { void reallocKVCache(); bool mKVCache; float mScale; - const int mExpandChunk = 64; + const int mExpandChunk = 2048; bool mIsDecode = false; bool mIsFirstDecode = true; int mPastLength = 0, mMaxLength = 0, mKv_seq_len = 0, mSoftMaxRemainChannels = 0; - std::shared_ptr mPastKey, mPastValue, mTempQK, mTempSoftMax; - int mNumHead = 0, mHeadDim = 0, mValueH = 0; + std::shared_ptr mPastKey, mPastValue; + std::shared_ptr mTempQK, mTempSoftMax; + int mNumHead = 0, mKvNumHead = 0, mHeadDim = 0, mValueH = 0; std::shared_ptr mKernel_qk; std::shared_ptr mKernel_softmax; std::shared_ptr mKernel_qkv; @@ -80,4 +82,5 @@ class AttentionBufExecution : public CommonExecution { } // namespace OpenCL } // namespace MNN #endif /* AttentionBufExecution_hpp */ +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ #endif /* MNN_OPENCL_BUFFER_CLOSED */ diff --git a/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp b/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp index 35c98970c..47b75864f 100644 --- a/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp @@ -400,7 +400,7 @@ class BinaryBufCreator : public OpenCLBackend::Creator { case BinaryOpOperation_NOTEQUAL: return new BinaryBufExecution(inputs, "convert_float4(-isnotequal(in0,in1))", op, backend); case BinaryOpOperation_MOD: - return new BinaryBufExecution(inputs, "fmod(in0,in1)", op, backend); + return new BinaryBufExecution(inputs, "in0-floor(sign(in1)*in0/(fabs(in1)>(float4)((float)0.0000001)?fabs(in1):(float4)((float)0.0000001)))*in1", op, backend); default: break; } diff --git a/source/backend/opencl/execution/buffer/ConvBufExecution.cpp b/source/backend/opencl/execution/buffer/ConvBufExecution.cpp index fc3778133..d0fdc0cda 100644 --- a/source/backend/opencl/execution/buffer/ConvBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/ConvBufExecution.cpp @@ -18,192 +18,7 @@ namespace MNN { namespace OpenCL { -std::pair, uint32_t> ConvBufCommonExecution::gws2dLwsTune(const std::shared_ptr &kernelW, const std::vector &gws, const std::string &kernelName, const uint32_t maxWorkGroupSize) { - MNN_ASSERT(gws.size() == 2); - auto kernel = kernelW->get(); - auto runtime = mOpenCLBackend->getOpenCLRuntime(); - auto maxWorkItemSizes = runtime->getMaxWorkItemSizes(); - MNN_ASSERT(maxWorkItemSizes.size() >= 2); - - auto& tunedLws = runtime->tunedLwsMap(); - auto& tuneLws = runtime->getTuneLwsMap(); - std::pair> info = std::make_pair(kernelName, gws); - if (tunedLws.find(info) != tunedLws.end()) { - //printf("ConvBuf2dGeneralLocalWS Found! gws:%d %d lws:%d %d\n", gws[0], gws[1], tunedLws[info][0], tunedLws[info][1]); - return tunedLws[info]; - } - std::pair, uint32_t> tuneLwsRes; - if(localWSTune(tuneLws, gws, kernelName, tuneLwsRes)){ - return tuneLwsRes; - } - - std::vector lws(3, 1); - std::vector lws_prefer(3, 1); - uint32_t min_cost = UINT_MAX; - - if(runtime->getCLTuneLevel() == Heavy) { - while(lws[1] <= gws[1] || lws[1] <= 6) { - lws[0] = 1; - while(lws[0] <= gws[0] || lws[0] <= 6) { - if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[0]*lws[1] <= maxWorkGroupSize) { - cl::Event event; - std::vector internalGlobalWS(2, 1); - for (size_t i = 0; i < gws.size(); ++i) { - internalGlobalWS[i] = ROUND_UP(gws[i], std::max((uint32_t)1, lws[i])); - } - cl_int res = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueNDRangeKernel( - kernel, cl::NullRange, - cl::NDRange(internalGlobalWS[0], internalGlobalWS[1]), - cl::NDRange(lws[0], lws[1]), - nullptr, &event); - MNN_CHECK_CL_SUCCESS(res, kernelName.c_str()); - - int cost_time = (int)mOpenCLBackend->getOpenCLRuntime()->getCostTime(&event); - if(cost_time < min_cost) { - min_cost = cost_time; - lws_prefer[0] = lws[0]; - lws_prefer[1] = lws[1]; - } - } - lws[0]<<=1; - } - lws[1]<<=1; - } - } else if(runtime->getCLTuneLevel() == Wide) { - while(lws[1] <= gws[1] || lws[1] <= 6) { - lws[0] = 1; - while(lws[0] <= gws[0] || lws[0] <= 6) { - if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[0]*lws[1] <= maxWorkGroupSize) { - cl::Event event; - std::vector internalGlobalWS(2, 1); - for (size_t i = 0; i < gws.size(); ++i) { - internalGlobalWS[i] = ROUND_UP(gws[i], std::max((uint32_t)1, lws[i])); - } - cl_int res = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueNDRangeKernel( - kernel, cl::NullRange, - cl::NDRange(internalGlobalWS[0], internalGlobalWS[1]), - cl::NDRange(lws[0], lws[1]), - nullptr, &event); - MNN_CHECK_CL_SUCCESS(res, kernelName.c_str()); - - int cost_time = (int)mOpenCLBackend->getOpenCLRuntime()->getCostTime(&event); - if(cost_time < min_cost) { - min_cost = cost_time; - lws_prefer[0] = lws[0]; - lws_prefer[1] = lws[1]; - } - } - do { - lws[0]<<=1; - } - while(((2*gws[0])%lws[0] > 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] > 6));//divisible powOfTwo lessThanSix - } - do { - lws[1]<<=1; - } - while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] > 6));//divisible powOfTwo lessThanSix - } - } else if(runtime->getCLTuneLevel() == Normal) { - while(lws[1] <= gws[1] && lws[1] <= 6) { - lws[0] = 1; - while(lws[0] <= gws[0] || lws[0] <= 6) { - if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[0]*lws[1] <= maxWorkGroupSize) { - cl::Event event; - std::vector internalGlobalWS(2, 1); - for (size_t i = 0; i < gws.size(); ++i) { - internalGlobalWS[i] = ROUND_UP(gws[i], std::max((uint32_t)1, lws[i])); - } - cl_int res = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueNDRangeKernel( - kernel, cl::NullRange, - cl::NDRange(internalGlobalWS[0], internalGlobalWS[1]), - cl::NDRange(lws[0], lws[1]), - nullptr, &event); - MNN_CHECK_CL_SUCCESS(res, kernelName.c_str()); - - int cost_time = (int)mOpenCLBackend->getOpenCLRuntime()->getCostTime(&event); - if(cost_time < min_cost) { - min_cost = cost_time; - lws_prefer[0] = lws[0]; - lws_prefer[1] = lws[1]; - } - } - do { - lws[0]<<=1; - } - while(((2*gws[0])%lws[0] > 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] > 6));//divisible powOfTwo lessThanSix - } - do { - lws[1]<<=1; - } - while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] <= 6));//divisible powOfTwo lessThanSix - } - } else if(runtime->getCLTuneLevel() == Fast) { - while(lws[1] <= gws[1] && lws[1] <= 6) { - lws[0] = 1; - while(lws[0] <= gws[0] && lws[0] <= 6) { - if(lws[0] <= maxWorkItemSizes[0] && lws[1] <= maxWorkItemSizes[1] && lws[0]*lws[1] <= maxWorkGroupSize) { - cl::Event event; - std::vector internalGlobalWS(2, 1); - for (size_t i = 0; i < gws.size(); ++i) { - internalGlobalWS[i] = ROUND_UP(gws[i], std::max((uint32_t)1, lws[i])); - } - cl_int res = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueNDRangeKernel( - kernel, cl::NullRange, - cl::NDRange(internalGlobalWS[0], internalGlobalWS[1]), - cl::NDRange(lws[0], lws[1]), - nullptr, &event); - MNN_CHECK_CL_SUCCESS(res, kernelName.c_str()); - - int cost_time = (int)mOpenCLBackend->getOpenCLRuntime()->getCostTime(&event); - if(cost_time < min_cost) { - min_cost = cost_time; - lws_prefer[0] = lws[0]; - lws_prefer[1] = lws[1]; - } - } - do { - lws[0]<<=1; - } - while(((2*gws[0])%lws[0] > 1) && (lws[0] & (lws[0] - 1)) != 0 && (lws[0] <= gws[0]) && (lws[0] <= 6));//divisible powOfTwo lessThanSix - } - do { - lws[1]<<=1; - } - while(((2*gws[1])%lws[1] > 1) && (lws[1] & (lws[1] - 1)) != 0 && (lws[1] <= gws[1]) && (lws[1] <= 6));//divisible powOfTwo lessThanSix - } - } else if(runtime->getCLTuneLevel() == None) { - // define not tune method to choose lws - if(runtime->getGpuMemType() == GpuMemObject::IMAGE) { - lws_prefer[0] = 8; - lws_prefer[1] = 4; - } else { - lws_prefer[0] = 0; - lws_prefer[1] = 0; - } - cl::Event event; - std::vector internalGlobalWS(2, 1); - for (size_t i = 0; i < gws.size(); ++i) { - internalGlobalWS[i] = ROUND_UP(gws[i], std::max((uint32_t)1, lws_prefer[i])); - } - cl_int res = CL_SUCCESS; - if(lws_prefer[0] == 0 || lws_prefer[1] == 0){ - res = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueNDRangeKernel( - kernel, cl::NullRange, cl::NDRange(internalGlobalWS[0], internalGlobalWS[1]), cl::NullRange, nullptr, &event); - }else{ - res = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueNDRangeKernel( - kernel, cl::NullRange, cl::NDRange(internalGlobalWS[0], internalGlobalWS[1]), cl::NDRange(lws_prefer[0], lws_prefer[1]), nullptr, &event); - } - MNN_CHECK_CL_SUCCESS(res, kernelName.c_str()); - min_cost = (int)mOpenCLBackend->getOpenCLRuntime()->getCostTime(&event); - } - - if (tunedLws.find(info) == tunedLws.end() && runtime->getCLTuneLevel() != None) { - //printf("ConvBuf2dGeneralLocalWS %d Insert! gws:%d %d, lws:%d %d, time:%dus\n", (int)tunedLws.size(), gws[0], gws[1], lws_prefer[0], lws_prefer[1], min_cost); - tunedLws.insert(std::make_pair(info, std::make_pair(lws_prefer, min_cost))); - } - return std::make_pair(lws_prefer, min_cost); -} ConvBufCommonExecution::ConvBufCommonExecution(Backend *backend) { mOpenCLBackend = static_cast(backend); } @@ -353,7 +168,7 @@ ConvBufExecution::ConvBufExecution(const std::vector &inputs, const st if (mResource->mConvGemmOptLevel > 0) { // Tile Match with mConvGemmOptLevel == 2 int tileK = 32; - int tileN = 128; + int tileN = 32; if(mResource->mConvGemmOptLevel == 1) { tileK = 8; @@ -512,11 +327,10 @@ ErrorCode ConvBufExecution::onResize(const std::vector &inputs, const if (mResource->mConvGemmOptLevel == 2) { // set large tile - int tileM = 128; - int tileN = 128; + int tileM = 32; + int tileN = 32; int tileK = 32; - int localM = 32; - int localN = 8; + int M = outputShape.at(0); int N = outputShape.at(3); int K = inputShape.at(3); @@ -555,13 +369,38 @@ ErrorCode ConvBufExecution::onResize(const std::vector &inputs, const mPreGlobalWorkSize[0] = ROUND_UP(mPreGlobalWorkSize[0], std::max((uint32_t)1, mPreLocalWorkSize[0])); mPreGlobalWorkSize[1] = ROUND_UP(mPreGlobalWorkSize[1], std::max((uint32_t)1, mPreLocalWorkSize[1])); } - std::set buildOptions = mResource->mBuildOptions; + std::set buildOptions; - // Can't add bias now, for slow speed -// buildOptions.emplace(" -DBIAS"); - - buildOptions.emplace(" -DGEMMK=0 -DKREG=1 -DKWG=32 -DKWI=2 -DMDIMA=32 -DMDIMC=32 -DMWG=128 -DNDIMB=8 -DNDIMC=8 -DNWG=128 -DSA=0 -DSB=0 -DSTRM=0 -DSTRN=1 -DVWM=2 -DVWN=8 -DOUTPUTMN"); - + uint32_t layout = 4; + uint32_t batch = 1; + auto param = getGemmParams({(uint32_t)alignM, (uint32_t)alignN, (uint32_t)alignK, layout, batch}, {openCLBuffer(mConvGemmInpTensor.get()), openCLBuffer(mResource->mFilter.get()), openCLBuffer(mConvGemmOutTensor.get())}, mOpenCLBackend->getOpenCLRuntime()); + + int GEMMK=param[0], KREG=param[1], KWG=param[2], KWI=param[3], MDIMA=param[4], MDIMC=param[5], MWG=param[6], NDIMB=param[7], NDIMC=param[8], NWG=param[9], SA=param[10], SB=param[11], STRM=param[12], STRN=param[13], VWM=param[14], VWN=param[15]; + buildOptions.emplace("-DGEMMK=" + std::to_string(GEMMK)); + buildOptions.emplace("-DKREG=" + std::to_string(KREG)); + buildOptions.emplace("-DKWG=" + std::to_string(KWG)); + buildOptions.emplace("-DKWI=" + std::to_string(KWI)); + buildOptions.emplace("-DMDIMA=" + std::to_string(MDIMA)); + buildOptions.emplace("-DMDIMC=" + std::to_string(MDIMC)); + buildOptions.emplace("-DMWG=" + std::to_string(MWG)); + buildOptions.emplace("-DNDIMB=" + std::to_string(NDIMB)); + buildOptions.emplace("-DNDIMC=" + std::to_string(NDIMC)); + buildOptions.emplace("-DNWG=" + std::to_string(NWG)); + buildOptions.emplace("-DSA=" + std::to_string(SA)); + buildOptions.emplace("-DSB=" + std::to_string(SB)); + buildOptions.emplace("-DSTRM=" + std::to_string(STRM)); + buildOptions.emplace("-DSTRN=" + std::to_string(STRN)); + buildOptions.emplace("-DVWM=" + std::to_string(VWM)); + buildOptions.emplace("-DVWN=" + std::to_string(VWN)); + if(layout >= 4) { + buildOptions.emplace("-DOUTPUTMN"); + } + + tileM = MWG; + tileN = NWG; + int localM = MDIMC; + int localN = NDIMC; + if(mOpenCLBackend->getOpenCLRuntime()->getGpuType() == GpuType::ADRENO) { buildOptions.emplace("-DUSE_CL_MAD=1"); buildOptions.emplace("-DRELAX_WORKGROUP_SIZE=1"); @@ -725,7 +564,7 @@ ErrorCode ConvBufExecution::onResize(const std::vector &inputs, const MNN_CHECK_CL_SUCCESS(ret, "setArg Conv1x1Buf Kernel Select"); std::pair, int> retTune; - retTune = gws2dLwsTune(kernel[knl_idx], globalWorkSize[knl_idx], kernelName[knl_idx] + info, maxWorkGroupSize); + retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); if(min_cost.first > retTune.second) { min_cost.first = retTune.second; min_cost.second = knl_idx; @@ -819,7 +658,7 @@ ErrorCode ConvBufExecution::onResize(const std::vector &inputs, const MNN_CHECK_CL_SUCCESS(ret, "setArg ConvBuf Kernel Select"); std::pair, int> retTune; - retTune = gws2dLwsTune(kernel[knl_idx], globalWorkSize[knl_idx], kernelName[knl_idx] + info, maxWorkGroupSize); + retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); if(min_cost.first > retTune.second) { min_cost.first = retTune.second; @@ -968,11 +807,14 @@ class ConvolutionBufCreator : public OpenCLBackend::Creator { if (((conv2dParams->quanParameter()->type() == 4) || (conv2dParams->quanParameter()->type() == 1) || (conv2dParams->quanParameter()->type() == 2))) { - // Todo: support int4 inputchannel % 4 not equal 4 + if ((1 == conv2dParams->quanParameter()->type() || 2 == conv2dParams->quanParameter()->type()) && conv2dParams->quanParameter()->has_scaleInt()) { + // Don't support IDST-int8 because of error + return nullptr; + } return new ConvBufLowMemoryExecution(inputs, outputs, op, backend); } else { - MNN_ERROR("OpenCL Conv buf low memory init error. For Opencl Backend, only support low memory mode of int8 or int4 dequantization currently.\n"); - MNN_ASSERT(false); + //MNN_ERROR("OpenCL Conv buf low memory init error. For Opencl Backend, only support low memory mode of int8 or int4 dequantization currently.\n"); + return nullptr; } } } diff --git a/source/backend/opencl/execution/buffer/ConvBufExecution.hpp b/source/backend/opencl/execution/buffer/ConvBufExecution.hpp index d5477c603..a1a523ca5 100644 --- a/source/backend/opencl/execution/buffer/ConvBufExecution.hpp +++ b/source/backend/opencl/execution/buffer/ConvBufExecution.hpp @@ -20,14 +20,14 @@ struct ConvBufResource { const Convolution2D *mConv2dParams; std::shared_ptr mKernelBuffer; std::shared_ptr mKernelImage; - std::shared_ptr dequantScale; - std::shared_ptr dequantOffset; + std::shared_ptr dequantScaleOffset; std::shared_ptr mFilter; std::shared_ptr mBias; int mKernelWidth; int mKernelHeight; int mOutputChannel; int mInputChannel; + int mBlockSize; std::vector mStrides{1, 1}; std::vector mDilations{1, 1}; std::set mBuildOptions; @@ -41,6 +41,7 @@ struct ConvBufResource { int mConvGemmOptLevel = 0; std::shared_ptr mRasterExe; bool mUseImage = false; + int mNumQuantBit = 0; }; class ConvBufCommonExecution { @@ -49,7 +50,6 @@ class ConvBufCommonExecution { ConvBufCommonExecution(const Convolution2D *op, Backend *backend); virtual ~ConvBufCommonExecution(); - std::pair, uint32_t> gws2dLwsTune(const std::shared_ptr &kernel, const std::vector &gws, const std::string &kernelName, const uint32_t maxWorkGroupSize); protected: std::shared_ptr mResource; OpenCLBackend *mOpenCLBackend; diff --git a/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.cpp b/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.cpp index a7b1cc817..36a4afd24 100644 --- a/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.cpp +++ b/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.cpp @@ -19,143 +19,168 @@ void ConvBufLowMemoryExecution::getInfoFromOpLowMemory(std::shared_ptrquan->type() == 4) { - mNumQuantBit = 8; - } else if (quanCommon->quan->type() == 1 || quanCommon->quan->type() == 2) { - mNumQuantBit = 4; - } else {/* More types to be supported. */} + mResource->mInputChannel = quanCommon->weight.size() / (mResource->mKernelWidth * mResource->mKernelHeight * mResource->mOutputChannel); + // set mResource->mNumQuantBit + if(quanCommon->canUseInt4){ + mResource->mNumQuantBit = 4; + }else{ + mResource->mNumQuantBit = 8; + } // src of alpha in CPU float * dequantAlpha = quanCommon->alpha.get(); + int totalCount = quanCommon->alpha.size(); + if (quanCommon->asymmetric) { + totalCount /= 2; + } int numAlpha = mResource->mOutputChannel; + mResource->mBlockSize = totalCount / numAlpha; // set mDequantScale mDequantOffset - int numAlphaPack = ROUND_UP(numAlpha, 16); - mResource->dequantScale.reset(Tensor::createDevice({numAlphaPack})); - mResource->dequantOffset.reset(Tensor::createDevice({numAlphaPack})); + int numAlphaPack = ROUND_UP(numAlpha, 4); - mOpenCLBackend->onAcquireBuffer(mResource->dequantScale.get(), Backend::STATIC); - mOpenCLBackend->onAcquireBuffer(mResource->dequantOffset.get(), Backend::STATIC); - cl::Buffer &dequantScaleBuffer = openCLBuffer(mResource->dequantScale.get()); - cl::Buffer &dequantOffsetBuffer = openCLBuffer(mResource->dequantOffset.get()); + mResource->dequantScaleOffset.reset(Tensor::createDevice({mResource->mBlockSize, numAlphaPack, 2})); + mOpenCLBackend->onAcquireBuffer(mResource->dequantScaleOffset.get(), Backend::STATIC); + cl::Buffer &dequantScaleOffsetBuffer = openCLBuffer(mResource->dequantScaleOffset.get()); // transfer data from src in cpu to dst in gpu int fpBytes = mOpenCLBackend->fpBytes(); - cl_int resBias, resScale, resOffset; - - - void * dequantScaleBufferMap = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(dequantScaleBuffer, true, CL_MAP_WRITE, 0, numAlphaPack * sizeof(int32_t), nullptr, nullptr, &resScale); - void * dequantOffsetBufferMap = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(dequantOffsetBuffer, true, CL_MAP_WRITE, 0, numAlphaPack * sizeof(int32_t), nullptr, nullptr, &resOffset); - - ::memset(dequantScaleBufferMap, -1, numAlphaPack * sizeof(int32_t)); - ::memset(dequantOffsetBufferMap, 0, numAlphaPack * sizeof(int32_t)); + cl_int resBias, resScaleOffset; - if (dequantScaleBufferMap != nullptr && dequantOffsetBufferMap != nullptr && resScale == CL_SUCCESS && resOffset == CL_SUCCESS) { + int mapSize = mResource->mBlockSize * numAlphaPack * sizeof(int32_t) * 2; + void * dequantScaleOffsetBufferMap = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(dequantScaleOffsetBuffer, true, CL_MAP_WRITE, 0, mapSize, nullptr, nullptr, &resScaleOffset); + // mBlockSize % 4 need equal 0 + if (dequantScaleOffsetBufferMap != nullptr && resScaleOffset == CL_SUCCESS) { if (quanCommon->asymmetric) { for (int i = 0; i < numAlpha; ++i) { - ((float *)dequantOffsetBufferMap)[i] = dequantAlpha[2 * i]; - ((float *)dequantScaleBufferMap)[i] = dequantAlpha[2 * i + 1]; + auto srcZ = dequantAlpha + i * mResource->mBlockSize * 2; + for(int j = 0; j < mResource->mBlockSize; ++j){ + float o = srcZ[2*j+0]; + float s = srcZ[2*j+1]; + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2] = s; + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2 + 1] = o; + } } } else { for (int i = 0; i < numAlpha; ++i) { - ((float *)dequantScaleBufferMap)[i] = dequantAlpha[i]; - ((float *)dequantOffsetBufferMap)[i] = 0.0f; + auto srcZ = dequantAlpha + i * mResource->mBlockSize; + for(int j = 0; j < mResource->mBlockSize; ++j){ + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2] = srcZ[j]; + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2 + 1] = 0.0f; + } } } } else { MNN_ERROR("Map error dequantBufferMap == nullptr \n"); MNN_ASSERT(false); } - mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(dequantScaleBuffer, dequantScaleBufferMap); - mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(dequantOffsetBuffer, dequantOffsetBufferMap); + mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(dequantScaleOffsetBuffer, dequantScaleOffsetBufferMap); // set mFilterDataPtr mFilterDataPtr = (void *)quanCommon->weight.get(); } + +bool ConvBufLowMemoryExecution::convertToQuantWeight1x1Buffer(cl::Buffer input, int pack) { +#ifdef LOG_VERBOSE + MNN_PRINT("start convertToQuantWeight1x1Buffer !\n"); +#endif + auto runtime = mOpenCLBackend->getOpenCLRuntime(); + std::string kernelName = "conv2d_1x1_weight_quant_buffer"; + if(mResource->mUseImage){ + kernelName = "conv2d_1x1_weight_quant_image"; + } + std::set buildOptions; + if (mResource->mNumQuantBit == 8) { + buildOptions.emplace("-DUSE_LOW_BIT_WEIGHT_INT8"); + } else if (mResource->mNumQuantBit == 4){ + // int4 case + buildOptions.emplace("-DUSE_LOW_BIT_WEIGHT_INT4"); + } else {/* More types to be supported. */} + if(mResource->mInputChannel % pack != 0){ + buildOptions.emplace("-DINPUT_CHANNEL_LEAVE"); + } + + mBufferToConv1x1Kernel = runtime->buildKernelWithCache("buffer_convert_quant", kernelName, buildOptions); + auto kernel = mBufferToConv1x1Kernel->get(); + uint32_t gws[2] = {static_cast(UP_DIV(mResource->mInputChannel, pack)), static_cast(mResource->mOutputChannel)}; + + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= kernel.setArg(idx++, gws[0]); + ret |= kernel.setArg(idx++, gws[1]); + ret |= kernel.setArg(idx++, input); + if(mResource->mUseImage){ + ret |= kernel.setArg(idx++, *mResource->mKernelImage.get()); + }else{ + ret |= kernel.setArg(idx++, *mResource->mKernelBuffer.get()); + } + ret |= kernel.setArg(idx++, mResource->mInputChannel); + ret |= kernel.setArg(idx++, mResource->mOutputChannel); + MNN_CHECK_CL_SUCCESS(ret, "setArg convertToQuantWeight1x1Buffer"); + + const uint32_t maxWorkGroupSize = static_cast(runtime->getMaxWorkGroupSize(mBufferToConv1x1Kernel)); + const std::vector lws = {16, std::max((uint32_t)1, maxWorkGroupSize / 16)}; + + cl::Event event; + cl_int res; + + std::vector roundUpGroupWorkSize(lws.size()); + for (size_t i = 0; i < lws.size(); ++i) { + roundUpGroupWorkSize[i] = ROUND_UP(gws[i], lws[i]); + } + + res = runtime->commandQueue().enqueueNDRangeKernel(kernel, cl::NullRange, + cl::NDRange(roundUpGroupWorkSize[0], roundUpGroupWorkSize[1]), + cl::NDRange(lws[0], lws[1]), nullptr, &event); + + event.wait(); + MNN_CHECK_CL_SUCCESS(res, "convertToQuantWeight1x1Buffer"); + +#ifdef LOG_VERBOSE + MNN_PRINT("end convertToQuantWeight1x1Buffer !\n"); +#endif + return true; +} + // set mKernelBuffer for the 1x1 kernels void ConvBufLowMemoryExecution::set1x1WeightLowMemory(int packCout, int packCin, void * filterDataPtr, std::shared_ptr & quanCommon) { cl_int res; std::shared_ptr filterBuffer(Tensor::createDevice({ROUND_UP(mResource->mOutputChannel, packCout), ROUND_UP(mResource->mInputChannel, packCin), mResource->mKernelWidth, mResource->mKernelHeight})); size_t buffer_size = filterBuffer->usize() / sizeof(float); + size_t cpy_size = mResource->mOutputChannel * mResource->mInputChannel * mResource->mKernelWidth * mResource->mKernelHeight * sizeof(char); float *dequantAlpha = quanCommon->alpha.get(); + cl::Buffer filterBufferCL(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size); + void *mapPtr = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(filterBufferCL, true, CL_MAP_WRITE, 0, buffer_size, nullptr, nullptr, &res); + if(mapPtr != nullptr && res == CL_SUCCESS){ + ::memcpy(mapPtr, filterDataPtr, cpy_size); + } else { + MNN_ERROR("set1x1WeightLowMemory: Map error ptrCL == nullptr \n"); + MNN_ASSERT(false); + } + mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(filterBufferCL, mapPtr); // shared part for all cases - if (mNumQuantBit == 8) { + if (mResource->mNumQuantBit == 8) { // int8 case buffer_size *= sizeof(int8_t); - } else if (mNumQuantBit == 4){ + } else if (mResource->mNumQuantBit == 4){ // int4 case buffer_size /= 2; } else {/* More types to be supported. */} // Use Image load weights - void *mapPtr = nullptr; - size_t row_pitch; - size_t slice_pitch; if(UP_DIV(mResource->mInputChannel, packCin) <= 16384 && ROUND_UP(mResource->mOutputChannel, packCout) <= 16384){ mResource->mUseImage = true; } if(mResource->mUseImage) { - if(mNumQuantBit == 4){ + if(mResource->mNumQuantBit == 4){ packCin *= 2; } size_t w = ROUND_UP(mResource->mOutputChannel, packCout); size_t h = UP_DIV(mResource->mInputChannel, packCin); - mResource->mKernelImage.reset(new cl::Image2D(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RGBA, CL_FLOAT), w, h, 0, nullptr, &res)); + mResource->mKernelImage.reset(new cl::Image2D(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RGBA, CL_SIGNED_INT32), w, h, 0, nullptr, &res)); if (nullptr == mResource->mKernelImage.get() || res != CL_SUCCESS) { - MNN_ERROR("Alloc Image %d x %d error, code:%d \n", w, h, res); - } - mapPtr = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapImage(*(mResource->mKernelImage.get()), true, CL_MAP_WRITE, {0, 0, 0}, {w, h, 1}, &row_pitch, &slice_pitch, nullptr, nullptr, &res); - if(mNumQuantBit == 4){ - row_pitch *= 2; + MNN_ERROR("Alloc Image %d x %d error, code:%d \n", (int)w, (int)h, (int)res); } } else{ mResource->mKernelBuffer.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size)); - mapPtr = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(*(mResource->mKernelBuffer.get()), true, CL_MAP_WRITE, 0, buffer_size, nullptr, nullptr, &res); - row_pitch = ROUND_UP(mResource->mOutputChannel, packCout) * packCin; - } - if(mapPtr != nullptr && res == CL_SUCCESS){ - for(int o = 0; o < mResource->mOutputChannel; o++){ - float zero = 0; - if(quanCommon->asymmetric){ - zero = (-dequantAlpha[2 * o + 1])/dequantAlpha[2 * o]; - } - int i = 0; - for(; i < mResource->mInputChannel ; i++){ - int bufferIdx = (i/packCin) * row_pitch + o*packCin + (i%packCin);//(Ci/packCin, Co/packCout * packCout * packCin) - int filterIdx = o*mResource->mInputChannel + i; - if (mNumQuantBit == 8) { - // int8 case - ((int8_t *)mapPtr)[bufferIdx] = (int8_t)(((int8_t *)filterDataPtr)[filterIdx]); - } else if (mNumQuantBit == 4){ - // int4 case - if (bufferIdx % 2 == 0) { - ((uint8_t *)mapPtr)[bufferIdx / 2] += (uint8_t)((((int8_t *)filterDataPtr)[filterIdx] + 8) * 16); - } else { - ((uint8_t *)mapPtr)[bufferIdx / 2] += (uint8_t)(((int8_t *)filterDataPtr)[filterIdx] + 8); - } - } else {/* More types to be supported. */} - } - for(; i < ROUND_UP(mResource->mInputChannel, packCin); i++){ - int bufferIdx = (i/packCin) * row_pitch + o*packCin + (i%packCin);//(Ci/packCin, Co/packCout * packCout * packCin) - if (mNumQuantBit == 8) { - // int8 case - ((int8_t *)mapPtr)[bufferIdx] = (int8_t)(zero); - } else if (mNumQuantBit == 4){ - // int4 case - if (bufferIdx % 2 == 0) { - ((uint8_t *)mapPtr)[bufferIdx / 2] += (uint8_t)((zero + 8) * 16); - } else { - ((uint8_t *)mapPtr)[bufferIdx / 2] += (uint8_t)(zero + 8); - } - } - } - } - } else { - MNN_ERROR("set1x1WeightLowMemory: Map error ptrCL == nullptr \n"); - MNN_ASSERT(false); - } - if(mResource->mUseImage){ - mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(*(mResource->mKernelImage.get()), mapPtr); - } else{ - mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(*(mResource->mKernelBuffer.get()), mapPtr); } + convertToQuantWeight1x1Buffer(filterBufferCL, packCin); } // set mFilter for the general kernels void ConvBufLowMemoryExecution::setGeneralWeightLowMemory(void* filterDataPtr, std::shared_ptr & quanCommon) { @@ -175,31 +200,24 @@ void ConvBufLowMemoryExecution::setGeneralWeightLowMemory(void* filterDataPtr, s ::memset(ptrCL, 0, buffer_size); const int copy_size = mResource->mKernelWidth * mResource->mKernelHeight * sizeof(int8_t); for(int oc=0; ocmOutputChannel; oc++) { - float zero = 0; - if(quanCommon->asymmetric){ - zero = (-dequantAlpha[2 * oc + 1])/dequantAlpha[2 * oc]; - } int ic = 0; for(; icmInputChannel; ic++) { ::memcpy((int8_t *)ptrCL + (oc * ROUND_UP(mResource->mInputChannel, 4) + ic) * mResource->mKernelWidth * mResource->mKernelHeight, ((int8_t *)filterDataPtr) + (oc * mResource->mInputChannel + ic) * mResource->mKernelWidth * mResource->mKernelHeight, copy_size); } - for(; icmInputChannel, 4); ic++) { - ((int8_t *)ptrCL)[(oc * ROUND_UP(mResource->mInputChannel, 4) + ic) * mResource->mKernelWidth * mResource->mKernelHeight] = (int8_t)(zero); - } } } else { MNN_ERROR("setGeneralWeightLowMemory: Map error ptrCL == nullptr \n"); } mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(filterBufferCL, ptrCL); // convert to NC4HW4 - if (mNumQuantBit == 8) { + if (mResource->mNumQuantBit == 8) { // ROUND_UP(IC, 4), UP_DIV(OC, 4) * mKernelWidth * mKernelHeight mResource->mFilter.reset(Tensor::createDevice({1, filterImageShape[1], 1, 4 * filterImageShape[0]})); mOpenCLBackend->onAcquireBuffer(mResource->mFilter.get(), Backend::STATIC); MNN::OpenCL::BufferConvertor bufferConvertor{mOpenCLBackend->getOpenCLRuntime()}; // filterBuffer shape: {OC, ROUND_UP(IC, 4), mKernelWidth, mKernelHeight} - bufferConvertor.convertToNC4HW4Buffer(filterBuffer.get(), MNN::OpenCL::CONV2D_FILTER, mResource->mFilter.get(), false, true, mLowMemoryFlag, mNumQuantBit); - } else if (mNumQuantBit == 4){ + bufferConvertor.convertToNC4HW4Buffer(filterBuffer.get(), MNN::OpenCL::CONV2D_FILTER, mResource->mFilter.get(), false, true, mLowMemoryFlag, mResource->mNumQuantBit); + } else if (mResource->mNumQuantBit == 4){ // ROUND_UP(IC, 4), UP_DIV(OC, 4) * mKernelWidth * mKernelHeight // For int4 case, data stored in mFilter should be uint8_t, // while "Tensor::createDevice" occupies more memory than "Tensor::createDevice". @@ -208,7 +226,7 @@ void ConvBufLowMemoryExecution::setGeneralWeightLowMemory(void* filterDataPtr, s mOpenCLBackend->onAcquireBuffer(mResource->mFilter.get(), Backend::STATIC); MNN::OpenCL::BufferConvertor bufferConvertor{mOpenCLBackend->getOpenCLRuntime()}; // filterBuffer shape: {OC, ROUND_UP(IC, 4), mKernelWidth, mKernelHeight} - bufferConvertor.convertToNC4HW4Buffer(filterBuffer.get(), MNN::OpenCL::CONV2D_FILTER, mResource->mFilter.get(), false, true, mLowMemoryFlag, mNumQuantBit); + bufferConvertor.convertToNC4HW4Buffer(filterBuffer.get(), MNN::OpenCL::CONV2D_FILTER, mResource->mFilter.get(), false, true, mLowMemoryFlag, mResource->mNumQuantBit); } else {/* More types to be supported. */} } else { MNN_ERROR("GetConvParams Error: filterDataPtr == nullptr. \n"); @@ -227,6 +245,7 @@ void ConvBufLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor const int inputWidth = inputShape.at(2); const int inputChannels = inputShape.at(3); const int inputChannelBlocks = UP_DIV(inputChannels, 4); + const int blockDim = mResource->mInputChannel / mResource->mBlockSize; std::string info = std::to_string(inputChannels) + "_" + std::to_string(outChannel) + "_" + std::to_string(mResource->mKernelHeight) + "_" + std::to_string(mResource->mKernelWidth) + "_" + std::to_string(mResource->mStrides[0]) + "_" + std::to_string(mResource->mStrides[1]) + "_" + std::to_string(mResource->mDilations[0]) + "_" + std::to_string(mResource->mDilations[1]); int inputImageShape[2] = {inputHeight, inputWidth}; int outputImageShape[2] = {height, width}; @@ -254,6 +273,9 @@ void ConvBufLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor if((outputShape.at(2) % itemW[knl_idx]) != 0 || (outputShape.at(1) % itemH[knl_idx]) != 0){ buildOption.emplace("-DBLOCK_LEAVE"); } + if(inputChannels % 4 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } kernel[knl_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("conv_2d_int_buf", kernelName[knl_idx], buildOption); uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(kernel[knl_idx])); @@ -264,8 +286,7 @@ void ConvBufLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor ret |= kernel[knl_idx]->get().setArg(idx++, globalWorkSize[knl_idx][1]); ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(input)); ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->mFilter.get())); - ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->dequantScale.get())); - ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->dequantOffset.get())); + ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->dequantScaleOffset.get())); ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->mBias.get())); ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(output)); ret |= kernel[knl_idx]->get().setArg(idx++, sizeof(inputImageShape), inputImageShape); @@ -279,9 +300,10 @@ void ConvBufLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(width, itemW[knl_idx])); ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(outChannel, 4)); ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(height, itemH[knl_idx])); + ret |= kernel[knl_idx]->get().setArg(idx++, blockDim); MNN_CHECK_CL_SUCCESS(ret, "setArg ConvBufLowMemory Kernel Select"); std::pair, int> retTune; - retTune = gws2dLwsTune(kernel[knl_idx], globalWorkSize[knl_idx], kernelName[knl_idx] + info, maxWorkGroupSize); + retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); if(min_cost.first > retTune.second) { min_cost.first = retTune.second; min_cost.second = knl_idx; @@ -298,6 +320,9 @@ void ConvBufLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor if((outputShape.at(2) % itemW[min_index]) != 0 || (outputShape.at(1) % itemH[min_index]) != 0){ buildOption.emplace("-DBLOCK_LEAVE"); } + if(inputChannels % 4 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("conv_2d_int_buf", kernelName[min_index], buildOption); uint32_t idx = 0; @@ -306,8 +331,7 @@ void ConvBufLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[1]); ret |= unit.kernel->get().setArg(idx++, openCLBuffer(input)); ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->mFilter.get())); - ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->dequantScale.get())); - ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->dequantOffset.get())); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->dequantScaleOffset.get())); ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->mBias.get())); ret |= unit.kernel->get().setArg(idx++, openCLBuffer(output)); ret |= unit.kernel->get().setArg(idx++, sizeof(inputImageShape), inputImageShape); @@ -321,6 +345,7 @@ void ConvBufLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor ret |= unit.kernel->get().setArg(idx++, UP_DIV(width, itemW[min_index])); ret |= unit.kernel->get().setArg(idx++, UP_DIV(outChannel, 4)); ret |= unit.kernel->get().setArg(idx++, UP_DIV(height, itemH[min_index])); + ret |= unit.kernel->get().setArg(idx++, blockDim); MNN_CHECK_CL_SUCCESS(ret, "setArg ConvBufLowMemory"); mOpenCLBackend->recordKernel2d(unit.kernel, mGlobalWorkSize, mLocalWorkSize); unit.globalWorkSize = {mGlobalWorkSize[0], mGlobalWorkSize[1]}; @@ -338,6 +363,8 @@ void ConvBufLowMemoryExecution::tuneGemmLowMemory(Tensor * input, Tensor * outpu const int width = outputShape.at(2); const int inputChannelBlocks = UP_DIV(inputChannels, 4); const int outputChannelBlocks = UP_DIV(outChannel, 4); + const int blockNum = mResource->mBlockSize; + const int blockDim = mResource->mInputChannel / mResource->mBlockSize; int global_y = batch * height; const int total_kernel = 5; @@ -353,9 +380,9 @@ void ConvBufLowMemoryExecution::tuneGemmLowMemory(Tensor * input, Tensor * outpu buildOption.emplace("-DWIDTH_HEIGHT_1"); } - if(inputChannels % 16 != 0){ + if(blockDim % 16 != 0){ buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); - } else if (mResource->mUseImage && mNumQuantBit == 4 && inputChannels % 32 != 0) { + } else if (mResource->mUseImage && mResource->mNumQuantBit == 4 && blockDim % 32 != 0) { // Image weight-int4 use load32 buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); } @@ -386,18 +413,20 @@ void ConvBufLowMemoryExecution::tuneGemmLowMemory(Tensor * input, Tensor * outpu }else{ ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->mKernelBuffer.get()); } - ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->dequantScale.get())); - ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->dequantOffset.get())); + ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->dequantScaleOffset.get())); ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->mBias.get())); ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(output)); ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(outputChannelBlocks)); ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(inputChannelBlocks)); + ret |= kernel[knl_idx]->get().setArg(idx++, inputChannels); ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(batch)); ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(height)); ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(width)); + ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(blockNum)); + ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(blockDim)); MNN_CHECK_CL_SUCCESS(ret, "setArg gemv_conv1x1_buf Kernel Select"); std::pair, int> retTune; - retTune = gws2dLwsTune(kernel[knl_idx], globalWorkSize[knl_idx], kernelName[knl_idx] + info, maxWorkGroupSize); + retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); if(min_cost.first > retTune.second) { min_cost.first = retTune.second; min_cost.second = knl_idx; @@ -420,21 +449,177 @@ void ConvBufLowMemoryExecution::tuneGemmLowMemory(Tensor * input, Tensor * outpu }else{ ret |= unit.kernel->get().setArg(idx++, *mResource->mKernelBuffer.get()); } - ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->dequantScale.get())); - ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->dequantOffset.get())); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->dequantScaleOffset.get())); ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->mBias.get())); ret |= unit.kernel->get().setArg(idx++, openCLBuffer(output)); ret |= unit.kernel->get().setArg(idx++, static_cast(outputChannelBlocks)); ret |= unit.kernel->get().setArg(idx++, static_cast(inputChannelBlocks)); + ret |= unit.kernel->get().setArg(idx++, static_cast(inputChannels)); ret |= unit.kernel->get().setArg(idx++, static_cast(batch)); ret |= unit.kernel->get().setArg(idx++, static_cast(height)); ret |= unit.kernel->get().setArg(idx++, static_cast(width)); + ret |= unit.kernel->get().setArg(idx++, static_cast(blockNum)); + ret |= unit.kernel->get().setArg(idx++, static_cast(blockDim)); MNN_CHECK_CL_SUCCESS(ret, "setArg gemv_conv1x1_buf"); mOpenCLBackend->recordKernel2d(unit.kernel, mGlobalWorkSize, mLocalWorkSize); unit.globalWorkSize = {mGlobalWorkSize[0], mGlobalWorkSize[1]}; unit.localWorkSize = {mLocalWorkSize[0], mLocalWorkSize[1]}; return; } +void ConvBufLowMemoryExecution::tuneGemvBatchLowMemory(Tensor * input, Tensor * output) { + mUnits.resize(3); + std::vector inputShape = tensorShapeFormat(input); + std::vector outputShape = tensorShapeFormat(output); + const int outChannel = outputShape.at(3); + const int inputChannels = inputShape.at(3); + const int batch = outputShape.at(0); + const int width_height = outputShape.at(1) * outputShape.at(2); + const int inputChannelBlocks = UP_DIV(inputChannels, 4); + const int outputChannelBlocks = UP_DIV(outChannel, 4); + const int blockNum = mResource->mBlockSize; + const int blockDim = mResource->mInputChannel / mResource->mBlockSize; + + int global_y = UP_DIV(batch, 4) * width_height; + const int total_kernel = 5; + std::string kernelName[total_kernel] = {"gemm_b4_c1_buf", "gemm_b4_c2_buf", "gemm_b4_c4_buf", "gemm_b4_c1_image", "gemm_b4_c2_image"}; + int itemC[total_kernel] = {1, 2, 4, 1, 2}; + int actual_kernel = total_kernel; + std::shared_ptr kernel[total_kernel]; + std::vector globalWorkSize[total_kernel]; + std::vector localWorkSize[total_kernel]; + std::pair min_cost(INT_MAX, 0);//(min_time, min_index) + std::set buildOption = mResource->mBuildOptions; + if(blockDim % 16 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } else if (mResource->mUseImage && mResource->mNumQuantBit == 4 && blockDim % 32 != 0) { + // Image weight-int4 use load32 + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } + std::string info = std::to_string(inputChannels) + "_" + std::to_string(outChannel); + // mResource->mInputChannel ROUND_UP to blockDim, avoid gemm overstep + mConvGemmInpTensor.reset(Tensor::createDevice({ROUND_UP(batch, 4) * ROUND_UP(ROUND_UP(mResource->mInputChannel, 4), blockDim) * width_height})); + mConvGemmOutTensor.reset(Tensor::createDevice({ROUND_UP(batch, 4) * ROUND_UP(mResource->mOutputChannel, 4) * width_height})); + mOpenCLBackend->onAcquireBuffer(mConvGemmInpTensor.get(), Backend::DYNAMIC); + mOpenCLBackend->onAcquireBuffer(mConvGemmOutTensor.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(mConvGemmOutTensor.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(mConvGemmInpTensor.get(), Backend::DYNAMIC); + + // reshape n*c/4*4*hw -> n/4*hw*c*4 + { + auto &unit = mUnits[0]; + mGlobalWorkSize = {static_cast(UP_DIV(mResource->mInputChannel, 4)), static_cast(UP_DIV(batch, 4)), static_cast(width_height)}; + unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm_quant_batch_buf", "reshape_nchw4_nhwc4", buildOption); + uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(unit.kernel)); + + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[0]); + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[1]); + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[2]); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(input)); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mConvGemmInpTensor.get())); + ret |= unit.kernel->get().setArg(idx++, static_cast(width_height)); + ret |= unit.kernel->get().setArg(idx++, static_cast(batch)); + ret |= unit.kernel->get().setArg(idx++, static_cast(inputChannels)); + ret |= unit.kernel->get().setArg(idx++, static_cast(inputChannelBlocks)); + MNN_CHECK_CL_SUCCESS(ret, "setArg reshape_nc4_cn4"); + mLocalWorkSize = localWS3DDefault(mGlobalWorkSize, maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), "reshape_nchw4_nhwc4", unit.kernel).first; + mOpenCLBackend->recordKernel3d(unit.kernel, mGlobalWorkSize, mLocalWorkSize); + unit.globalWorkSize = {mGlobalWorkSize[0], mGlobalWorkSize[1], mGlobalWorkSize[2]}; + unit.localWorkSize = {mLocalWorkSize[0], mLocalWorkSize[1], mLocalWorkSize[2]}; + } + // gemm + { + auto &unit = mUnits[1]; + int knl_idx = 0; + actual_kernel = 3; + if(mResource->mUseImage){ + knl_idx = 3; + actual_kernel = total_kernel; + } + for (; knl_idx < actual_kernel; knl_idx++) { + kernel[knl_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm_quant_batch_buf", kernelName[knl_idx], buildOption); + uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(kernel[knl_idx])); + + globalWorkSize[knl_idx] = {static_cast(UP_DIV(outChannel, itemC[knl_idx])), static_cast(global_y)}; + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= kernel[knl_idx]->get().setArg(idx++, globalWorkSize[knl_idx][0]); + ret |= kernel[knl_idx]->get().setArg(idx++, globalWorkSize[knl_idx][1]); + ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mConvGemmInpTensor.get())); + if(mResource->mUseImage){ + ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->mKernelImage.get()); + }else{ + ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->mKernelBuffer.get()); + } + ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->dequantScaleOffset.get())); + ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->mBias.get())); + ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mConvGemmOutTensor.get())); + ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(outputChannelBlocks)); + ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(inputChannelBlocks)); + ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(blockNum)); + ret |= kernel[knl_idx]->get().setArg(idx++, static_cast(blockDim)); + MNN_CHECK_CL_SUCCESS(ret, "setArg gemv_conv1x1_buf Kernel Select"); + std::pair, int> retTune; + retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); + if(min_cost.first > retTune.second) { + min_cost.first = retTune.second; + min_cost.second = knl_idx; + mLocalWorkSize = {retTune.first[0], retTune.first[1]}; + } + } + int min_index = min_cost.second; + mGlobalWorkSize = {globalWorkSize[min_index][0], globalWorkSize[min_index][1]}; + + + unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm_quant_batch_buf", kernelName[min_index], buildOption); + //MNN_PRINT("Kernel is %d.\n", min_index); + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[0]); + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[1]); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mConvGemmInpTensor.get())); + if(mResource->mUseImage){ + ret |= unit.kernel->get().setArg(idx++, *mResource->mKernelImage.get()); + }else{ + ret |= unit.kernel->get().setArg(idx++, *mResource->mKernelBuffer.get()); + } + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->dequantScaleOffset.get())); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->mBias.get())); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mConvGemmOutTensor.get())); + ret |= unit.kernel->get().setArg(idx++, static_cast(outputChannelBlocks)); + ret |= unit.kernel->get().setArg(idx++, static_cast(inputChannelBlocks)); + ret |= unit.kernel->get().setArg(idx++, static_cast(blockNum)); + ret |= unit.kernel->get().setArg(idx++, static_cast(blockDim)); + MNN_CHECK_CL_SUCCESS(ret, "setArg gemv_conv1x1_buf"); + mOpenCLBackend->recordKernel2d(unit.kernel, mGlobalWorkSize, mLocalWorkSize); + unit.globalWorkSize = {mGlobalWorkSize[0], mGlobalWorkSize[1]}; + unit.localWorkSize = {mLocalWorkSize[0], mLocalWorkSize[1]}; + } + // reshape n/4*hw*c*4 -> n*c/4*4*hw + { + auto &unit = mUnits[2]; + mGlobalWorkSize = {static_cast(UP_DIV(mResource->mOutputChannel, 4)), static_cast(UP_DIV(batch, 4)), static_cast(width_height)}; + unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm_quant_batch_buf", "reshape_nhwc4_nchw4", buildOption); + uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(unit.kernel)); + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[0]); + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[1]); + ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[2]); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mConvGemmOutTensor.get())); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(output)); + ret |= unit.kernel->get().setArg(idx++, static_cast(width_height)); + ret |= unit.kernel->get().setArg(idx++, static_cast(batch)); + ret |= unit.kernel->get().setArg(idx++, static_cast(outputChannelBlocks)); + MNN_CHECK_CL_SUCCESS(ret, "setArg reshape_cn4_nc4"); + mLocalWorkSize = localWS3DDefault(mGlobalWorkSize, maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), "reshape_nhwc4_nchw4", unit.kernel).first; + mOpenCLBackend->recordKernel3d(unit.kernel, mGlobalWorkSize, mLocalWorkSize); + unit.globalWorkSize = {mGlobalWorkSize[0], mGlobalWorkSize[1], mGlobalWorkSize[2]}; + unit.localWorkSize = {mLocalWorkSize[0], mLocalWorkSize[1], mLocalWorkSize[2]}; + } + return; +} ConvBufLowMemoryExecution::ConvBufLowMemoryExecution(const std::vector &inputs, const std::vector &outputs, const MNN::Op *op, Backend *backend) : ConvBufCommonExecution(op->main_as_Convolution2D(), backend), CommonExecution(backend, op) { #ifdef LOG_VERBOSE @@ -454,7 +639,6 @@ ConvBufLowMemoryExecution::ConvBufLowMemoryExecution(const std::vector mResource->mKernelWidth = conv2dCommonParams->kernelX(); mResource->mKernelHeight = conv2dCommonParams->kernelY(); mResource->mOutputChannel = conv2dCommonParams->outputCount(); - mResource->mInputChannel = conv2dCommonParams->inputCount(); std::shared_ptr quanCommon; // set mDequantScale, mDequantOffset, mFilterDataPtr // prepare mDequantScale mDequantOffset mFilterDataPtr @@ -473,15 +657,15 @@ ConvBufLowMemoryExecution::ConvBufLowMemoryExecution(const std::vector } else if (conv2dCommonParams->relu6()) { mResource->mBuildOptions.emplace("-DRELU6"); } - if (mNumQuantBit == 8) { + if (mResource->mNumQuantBit == 8) { // int8 case mResource->mBuildOptions.emplace("-DUSE_LOW_BIT_WEIGHT_INT8"); - } else if (mNumQuantBit == 4){ + } else if (mResource->mNumQuantBit == 4){ // int4 case mResource->mBuildOptions.emplace("-DUSE_LOW_BIT_WEIGHT_INT4"); } else {/* More types to be supported. */} #ifdef LOG_VERBOSE - MNN_PRINT("end ConvExecution init !\n"); + MNN_PRINT("end ConvBufLowMemoryExecution init !\n"); #endif } @@ -511,7 +695,7 @@ bool ConvBufLowMemoryExecution::onClone(Backend* bn, const Op* op, Execution** d ErrorCode ConvBufLowMemoryExecution::onEncode(const std::vector &inputs, const std::vector &outputs) { #ifdef LOG_VERBOSE - MNN_PRINT("Start ConvExecution onResize !\n"); + MNN_PRINT("Start ConvBufLowMemoryExecution onResize !\n"); #endif mUnits.resize(1); auto input = inputs[0]; @@ -520,13 +704,20 @@ ErrorCode ConvBufLowMemoryExecution::onEncode(const std::vector &input mPaddings[0] = padding.second;//padY mPaddings[1] = padding.first;//padX // onclone default use conv1x1Opt, need reset + std::vector outputShape = tensorShapeFormat(output); + const int batch = outputShape.at(0); + bool isMali = mOpenCLBackend->getOpenCLRuntime()->getGpuType() == MALI; if (mResource->mConv1x1Opt) { - tuneGemmLowMemory(input, output); + if(batch > 1 && isMali){ + tuneGemvBatchLowMemory(input, output); + }else{ + tuneGemmLowMemory(input, output); + } } else { tuneGeneralCaseLowMemory(input, output); } #ifdef LOG_VERBOSE - MNN_PRINT("end ConvExecution onResize !\n"); + MNN_PRINT("end ConvBufLowMemoryExecution onResize !\n"); #endif return NO_ERROR; } diff --git a/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.hpp b/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.hpp index 8a99c7afc..de0938c7b 100644 --- a/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.hpp +++ b/source/backend/opencl/execution/buffer/ConvBufLowMemoryExecution.hpp @@ -29,12 +29,16 @@ class ConvBufLowMemoryExecution : public ConvBufCommonExecution, public CommonEx void setGeneralWeightLowMemory(void * filterDataPtr, std::shared_ptr & quanCommon); void tuneGeneralCaseLowMemory(Tensor * input, Tensor * output); void tuneGemmLowMemory(Tensor * input, Tensor * output); + void tuneGemvBatchLowMemory(Tensor * input, Tensor * output); + bool convertToQuantWeight1x1Buffer(cl::Buffer input, int pack); std::vector mPaddings{0, 0}; std::vector mGlobalWorkSize{1, 1, 1}; std::vector mLocalWorkSize{1, 1, 1, 1}; void *mFilterDataPtr = nullptr; bool mLowMemoryFlag = false; - int mNumQuantBit = 0; + std::shared_ptr mConvGemmInpTensor; + std::shared_ptr mConvGemmOutTensor; + std::shared_ptr mBufferToConv1x1Kernel = nullptr; }; } // namespace OpenCL diff --git a/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp b/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp index 5ddba38fb..52c0d39c2 100644 --- a/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp +++ b/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp @@ -30,7 +30,44 @@ bool ConvBufWinograd::valid(const Convolution2DCommon* common, const Tensor* inp return input->width() * input->height() <= 4096; } - return input->channel() >= 32 && output->channel() >= 32 && input->width() < output->channel(); + bool valid = input->channel() >= 32 && output->channel() >= 32 && input->width() < output->channel(); + valid = valid || (input->channel() >= 64 && output->channel() >= 64); + return valid; +} + +void ConvBufWinograd::convertWeightFormat(cl::Buffer& buffer, const int tileK, const int tileN) { + auto runtime = mOpenCLBackend->getOpenCLRuntime(); + + auto icPad = ROUND_UP(mCi, tileK); + auto ocPad = ROUND_UP(mCo, tileN); + + auto kernel = runtime->buildKernel("winogradTransform_buf", "winoTransWeightBuf2_3_1", {}); + uint32_t gws[2] = {static_cast(icPad), static_cast(ocPad)}; + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= kernel->get().setArg(idx++, gws[0]); + ret |= kernel->get().setArg(idx++, gws[1]); + ret |= kernel->get().setArg(idx++, buffer); + ret |= kernel->get().setArg(idx++, openCLBuffer(mResource->mWeight.get())); + ret |= kernel->get().setArg(idx++, mCi); + ret |= kernel->get().setArg(idx++, mCo); + ret |= kernel->get().setArg(idx++, icPad); + ret |= kernel->get().setArg(idx++, ocPad); + + MNN_CHECK_CL_SUCCESS(ret, "setArg conv-winograd convertWeightFormat"); + const std::vector lws = {8, 8}; + cl::Event event; + cl_int res; + std::vector roundUpGroupWorkSize(lws.size()); + for (size_t i = 0; i < lws.size(); ++i) { + roundUpGroupWorkSize[i] = ROUND_UP(gws[i], lws[i]); + } + res = runtime->commandQueue().enqueueNDRangeKernel(kernel->get(), cl::NullRange, + cl::NDRange(roundUpGroupWorkSize[0], roundUpGroupWorkSize[1]), + cl::NDRange(lws[0], lws[1]), nullptr, &event); + MNN_CHECK_CL_SUCCESS(res, "conv-winograd convertWeightFormat"); + //event.wait(); + return; } ConvBufWinograd::ConvBufWinograd(const MNN::Op* op, Backend* backend) : CommonExecution(backend, op) { @@ -50,10 +87,10 @@ ConvBufWinograd::ConvBufWinograd(const MNN::Op* op, Backend* backend) : CommonEx std::shared_ptr quanCommon; ConvolutionCommon::getConvParameters(&quanCommon, backend, conv2D, &filterDataPtr, &weightSize); - int oc = mResource->mCommon->outputCount(); - int ic = weightSize / oc / mResource->mCommon->kernelX() / mResource->mCommon->kernelY(); - auto ocC4 = UP_DIV(oc, 4); - auto icC4 = UP_DIV(ic, 4); + mCo = mResource->mCommon->outputCount(); + mCi = weightSize / mCo / mResource->mCommon->kernelX() / mResource->mCommon->kernelY(); + auto ocC4 = UP_DIV(mCo, 4); + auto icC4 = UP_DIV(mCi, 4); auto queue = runTime->commandQueue(); auto imageChannelType = CL_HALF_FLOAT; @@ -66,7 +103,7 @@ ConvBufWinograd::ConvBufWinograd(const MNN::Op* op, Backend* backend) : CommonEx if (mResource->mUseSubgroup) { // create buffer for intel subgroup cl_int ret_code; - size_t bias_element = ALIGN_UP4(oc); + size_t bias_element = ALIGN_UP4(mCo); size_t buffer_size; if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()) { buffer_size = bias_element * sizeof(half_float::half); @@ -74,7 +111,7 @@ ConvBufWinograd::ConvBufWinograd(const MNN::Op* op, Backend* backend) : CommonEx buffer_size = bias_element * sizeof(float); } - mResource->mBias.reset(Tensor::createDevice({1, 1, 1, (int)ALIGN_UP4(oc)})); + mResource->mBias.reset(Tensor::createDevice({1, 1, 1, (int)ALIGN_UP4(mCo)})); mOpenCLBackend->onAcquireBuffer(mResource->mBias.get(), Backend::STATIC); cl::Buffer &bias_buffer = *(cl::Buffer *)mResource->mBias->buffer().device; @@ -84,19 +121,19 @@ ConvBufWinograd::ConvBufWinograd(const MNN::Op* op, Backend* backend) : CommonEx } ::memset(bias_ptr, 0, buffer_size); if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()) { - for(int i=0; ibias()->data()[i]; } } else { - ::memcpy(bias_ptr, conv2D->bias()->data(), oc*sizeof(float)); + ::memcpy(bias_ptr, conv2D->bias()->data(), mCo*sizeof(float)); } queue.enqueueUnmapMemObject(bias_buffer, bias_ptr); - auto ocC16 = UP_DIV(oc, 16); - auto icC16 = UP_DIV(ic, 16); + auto ocC16 = UP_DIV(mCo, 16); + auto icC16 = UP_DIV(mCi, 16); std::shared_ptr sourceWeight( - Tensor::create(std::vector{oc, ic, ky, kx}, (void*)(filterDataPtr), Tensor::CAFFE)); + Tensor::create(std::vector{mCo, mCi, ky, kx}, (void*)(filterDataPtr), Tensor::CAFFE)); int unit = UNIT; int kernelSize = kx; @@ -136,8 +173,9 @@ ConvBufWinograd::ConvBufWinograd(const MNN::Op* op, Backend* backend) : CommonEx }else #endif /* MNN_SUPPORT_INTEL_SUBGROUP */ { + cl_int ret_code; - size_t bias_element = ALIGN_UP4(oc); + size_t bias_element = ALIGN_UP4(mCo); size_t buffer_size; if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()) { buffer_size = bias_element * sizeof(half_float::half); @@ -145,63 +183,52 @@ ConvBufWinograd::ConvBufWinograd(const MNN::Op* op, Backend* backend) : CommonEx buffer_size = bias_element * sizeof(float); } - mResource->mBias.reset(Tensor::createDevice({1, 1, 1, (int)ALIGN_UP4(oc)})); + mResource->mBias.reset(Tensor::createDevice({1, 1, 1, (int)ALIGN_UP4(mCo)})); mOpenCLBackend->onAcquireBuffer(mResource->mBias.get(), Backend::STATIC); cl::Buffer &bias_buffer = *(cl::Buffer *)mResource->mBias->buffer().device; - + auto bias_ptr = queue.enqueueMapBuffer(bias_buffer, CL_TRUE, CL_MAP_WRITE, 0, buffer_size, nullptr, nullptr, &ret_code); if(bias_ptr == nullptr || ret_code) { MNN_ERROR("clBuffer map error!\n"); } ::memset(bias_ptr, 0, buffer_size); if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()) { - for(int i=0; ibias()->data()[i]; } } else { - ::memcpy(bias_ptr, conv2D->bias()->data(), oc*sizeof(float)); + ::memcpy(bias_ptr, conv2D->bias()->data(), mCo*sizeof(float)); } queue.enqueueUnmapMemObject(bias_buffer, bias_ptr); - - std::shared_ptr sourceWeight( - Tensor::create(std::vector{oc, ic, ky, kx}, (void*)(filterDataPtr), Tensor::CAFFE)); - int unit = UNIT; int kernelSize = kx; - Math::WinogradGenerater generator(unit, kernelSize, INTERP); int alpha = unit + kernelSize - 1; - auto weightDest = generator.allocTransformWeight(sourceWeight.get()); - generator.transformWeight(weightDest.get(), sourceWeight.get()); - auto weightDestSize = weightDest->size(); - - buffer_size = weightDest->elementSize(); - if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()) { - buffer_size *= sizeof(half_float::half); - } else { - buffer_size *= sizeof(float); - } - mResource->mWeight.reset(Tensor::createDevice({1, ocC4 * alpha * alpha, icC4 * 4, 4}));//NHWC + int tileK = 16; + int tileN = 32; + + std::shared_ptr tmpFilterTensor; + tmpFilterTensor.reset(Tensor::createDevice({mCo * mCi * ky * kx})); + mOpenCLBackend->onAcquireBuffer(tmpFilterTensor.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(tmpFilterTensor.get(), Backend::DYNAMIC); + + mResource->mWeight.reset(Tensor::createDevice({alpha * alpha * ROUND_UP(mCo, tileN) * ROUND_UP(mCi, tileK)}));//NHWC mOpenCLBackend->onAcquireBuffer(mResource->mWeight.get(), Backend::STATIC); - cl::Buffer &weightBuffer = *(cl::Buffer *)mResource->mWeight->buffer().device; - - auto weight_ptr = queue.enqueueMapBuffer(weightBuffer, CL_TRUE, CL_MAP_WRITE, 0, buffer_size, nullptr, nullptr, &ret_code); - if(weight_ptr != nullptr && ret_code == CL_SUCCESS){ - if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()){ - for(int i=0; ielementSize(); i++) { - ((half_float::half*)weight_ptr)[i] = (half_float::half)(weightDest->host()[i]); - } - }else{ - ::memcpy(weight_ptr, weightDest->host(), buffer_size); - } - } else{ - MNN_ERROR("Map error weightPtr == nullptr \n"); + buffer_size = mCo * mCi * ky * kx * sizeof(float); + cl::Buffer& weightBufferCL = openCLBuffer(tmpFilterTensor.get()); + + cl_int res; + auto ptrCL = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(weightBufferCL, true, CL_MAP_WRITE, 0, buffer_size, nullptr, nullptr, &res); + if(ptrCL != nullptr && res == CL_SUCCESS) { + ::memcpy(ptrCL, filterDataPtr, buffer_size); + }else{ + MNN_ERROR("Map weightBufferCL error:%d, ptrCL == nullptr \n", res); } - - queue.enqueueUnmapMemObject(weightBuffer, weight_ptr); + mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(weightBufferCL, ptrCL); + convertWeightFormat(weightBufferCL, tileK, tileN); } } @@ -431,11 +458,13 @@ ErrorCode ConvBufWinograd::onEncode(const std::vector& inputs, const st } else #endif /* MNN_SUPPORT_INTEL_SUBGROUP */ { + int tileM = 16; + int tileN = 32; + int tileK = 16; mSource.reset(Tensor::createDevice( - std::vector{alpha * alpha, input->channel(), ROUND_UP(UP_DIV(wUnit * hUnit, 4), 2), 4}, - Tensor::CAFFE_C4)); + std::vector{alpha * alpha * ROUND_UP(input->channel(), tileK) * ROUND_UP(wUnit * hUnit, tileM)})); mDest.reset(Tensor::createDevice( - std::vector{4, wUnit * hUnit, UP_DIV(output->channel(), 4), alpha * alpha}, Tensor::CAFFE_C4)); + std::vector{alpha * alpha * ROUND_UP(wUnit * hUnit, tileM) * ROUND_UP(output->channel(), tileN)})); mOpenCLBackend->onAcquireBuffer(mSource.get(), Backend::DYNAMIC); mOpenCLBackend->onAcquireBuffer(mDest.get(), Backend::DYNAMIC); @@ -467,13 +496,16 @@ ErrorCode ConvBufWinograd::onEncode(const std::vector& inputs, const st } } + int hCount = hUnit; + int wCount = wUnit; + int M_pack = ROUND_UP(wCount * hCount, tileM); + int K_pack = ROUND_UP(input->channel(), tileK); + int N_pack = ROUND_UP(output->channel(), tileN); for (int b = 0; b < input->batch(); ++b) { - int hCount = hUnit; - int wCount = wUnit; // Source Transform { - mGWS_S[b] = {static_cast(wCount * hCount), static_cast(icC4)}; + mGWS_S[b] = {static_cast(M_pack), static_cast(UP_DIV(K_pack, 4))}; int index = 0; cl_int ret = CL_SUCCESS; ret |= mUnits[b * 3].kernel->get().setArg(index++, mGWS_S[b][0]); @@ -487,8 +519,10 @@ ErrorCode ConvBufWinograd::onEncode(const std::vector& inputs, const st ret |= mUnits[b * 3].kernel->get().setArg(index++, input->width()); ret |= mUnits[b * 3].kernel->get().setArg(index++, input->height()); ret |= mUnits[b * 3].kernel->get().setArg(index++, icC4); + ret |= mUnits[b * 3].kernel->get().setArg(index++, M_pack); + ret |= mUnits[b * 3].kernel->get().setArg(index++, K_pack); ret |= mUnits[b * 3].kernel->get().setArg(index++, b); - MNN_CHECK_CL_SUCCESS(ret, "setArg ConvWinogradBuf SubGroup Source Trans"); + MNN_CHECK_CL_SUCCESS(ret, "setArg ConvWinogradBuf Source Trans"); std::string kernelName = "winoTransSrcBuf"; mLWS_S[b] = localWS2DDefault(mGWS_S[b], mMaxWGS_S[b], mOpenCLBackend->getOpenCLRuntime(), kernelName + info, mUnits[b * 3].kernel).first; @@ -498,70 +532,86 @@ ErrorCode ConvBufWinograd::onEncode(const std::vector& inputs, const st } // MatMul + { - auto gemmHeight = ocC4; - auto gemmWidth = UP_DIV(wCount * hCount, 4); - - const int total_kernel = 2; - const std::string kernelName[total_kernel] = {"gemm_buf", "gemm_buf2"}; - int itemW[total_kernel] = {1, 2}; - - int actual_kernel = total_kernel; - if (mOpenCLBackend->getOpenCLRuntime()->getCLTuneLevel() == Normal || mOpenCLBackend->getOpenCLRuntime()->getCLTuneLevel() == Fast || mOpenCLBackend->getOpenCLRuntime()->getCLTuneLevel() == None) { - actual_kernel = 1; + int loop = alpha * alpha; + int e_pack = ROUND_UP(wCount * hCount, tileM); + int l_pack = ROUND_UP(input->channel(), tileK); + int h_pack = ROUND_UP(output->channel(), tileN); + + std::set buildOptions; + uint32_t layout = 4; + auto param = getGemmParams({(uint32_t)e_pack, (uint32_t)h_pack, (uint32_t)l_pack, layout, (uint32_t)loop}, {openCLBuffer(mSource.get()), openCLBuffer(mResource->mWeight.get()), openCLBuffer(mDest.get())}, mOpenCLBackend->getOpenCLRuntime()); + + int GEMMK=param[0], KREG=param[1], KWG=param[2], KWI=param[3], MDIMA=param[4], MDIMC=param[5], MWG=param[6], NDIMB=param[7], NDIMC=param[8], NWG=param[9], SA=param[10], SB=param[11], STRM=param[12], STRN=param[13], VWM=param[14], VWN=param[15]; + buildOptions.emplace("-DGEMMK=" + std::to_string(GEMMK)); + buildOptions.emplace("-DKREG=" + std::to_string(KREG)); + buildOptions.emplace("-DKWG=" + std::to_string(KWG)); + buildOptions.emplace("-DKWI=" + std::to_string(KWI)); + buildOptions.emplace("-DMDIMA=" + std::to_string(MDIMA)); + buildOptions.emplace("-DMDIMC=" + std::to_string(MDIMC)); + buildOptions.emplace("-DMWG=" + std::to_string(MWG)); + buildOptions.emplace("-DNDIMB=" + std::to_string(NDIMB)); + buildOptions.emplace("-DNDIMC=" + std::to_string(NDIMC)); + buildOptions.emplace("-DNWG=" + std::to_string(NWG)); + buildOptions.emplace("-DSA=" + std::to_string(SA)); + buildOptions.emplace("-DSB=" + std::to_string(SB)); + buildOptions.emplace("-DSTRM=" + std::to_string(STRM)); + buildOptions.emplace("-DSTRN=" + std::to_string(STRN)); + buildOptions.emplace("-DVWM=" + std::to_string(VWM)); + buildOptions.emplace("-DVWN=" + std::to_string(VWN)); + if(layout >= 4) { + buildOptions.emplace("-DOUTPUTMN"); } - - std::shared_ptr kernel[total_kernel]; - std::vector globalWorkSize[total_kernel]; - std::vector localWorkSize[total_kernel]; - std::pair min_cost(UINT_MAX, 0); //(min_time, min_index) - for (int knl_idx = 0; knl_idx < actual_kernel; knl_idx++) { - kernel[knl_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm_buf", kernelName[knl_idx], basic); - uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(kernel[knl_idx])); - - globalWorkSize[knl_idx] = {static_cast(UP_DIV(gemmWidth, itemW[knl_idx]) * gemmHeight), static_cast(alpha * alpha)}; - uint32_t index = 0; - cl_int ret = CL_SUCCESS; - ret |= kernel[knl_idx]->get().setArg(index++, globalWorkSize[knl_idx][0]); - ret |= kernel[knl_idx]->get().setArg(index++, globalWorkSize[knl_idx][1]); - ret |= kernel[knl_idx]->get().setArg(index++, openCLBuffer(mSource.get())); - ret |= kernel[knl_idx]->get().setArg(index++, openCLBuffer(mResource->mWeight.get())); - ret |= kernel[knl_idx]->get().setArg(index++, openCLBuffer(mDest.get())); - ret |= kernel[knl_idx]->get().setArg(index++, gemmWidth); - ret |= kernel[knl_idx]->get().setArg(index++, gemmHeight); - ret |= kernel[knl_idx]->get().setArg(index++, icC4); - ret |= kernel[knl_idx]->get().setArg(index++, alpha * alpha); - MNN_CHECK_CL_SUCCESS(ret, "setArg ConvWinogradBuf SubGroup MatMul Kernel Select"); - - std::pair, uint32_t> retTune; - retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); - // printf("gemm %d, %d\n", knl_idx, retTune.second); - if (min_cost.first > retTune.second) { - min_cost.first = retTune.second; - min_cost.second = knl_idx; - mLWS_M[b] = {retTune.first[0], retTune.first[1]}; - } + + int tileM = MWG; + int tileN = NWG; + int localM = MDIMC; + int localN = NDIMC; + + if(mOpenCLBackend->getOpenCLRuntime()->getGpuType() == GpuType::ADRENO) { + buildOptions.emplace("-DUSE_CL_MAD=1"); + buildOptions.emplace("-DRELAX_WORKGROUP_SIZE=1"); } - int min_index = min_cost.second; - // mKernel = kernel[min_index]; - mGWS_M[b] = {globalWorkSize[min_index][0], globalWorkSize[min_index][1]}; - mUnits[b * 3 + 1].kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm_buf", kernelName[min_index], basic); - int index = 0; + if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()){ + buildOptions.emplace(" -DPRECISION=16"); + } else { + buildOptions.emplace(" -DPRECISION=32"); + } + + mUnits[b * 3 + 1].kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("matmul_params_buf", "XgemmBatched", buildOptions); + + int out_per_thread_m = tileM / localM; + int out_per_thread_n = tileN / localN; + + mGWS_M[b] = {static_cast(e_pack/out_per_thread_m), static_cast(h_pack/out_per_thread_n), static_cast(loop)}; + mLWS_M[b] = {static_cast(localM), static_cast(localN), 1}; + + float alpha = 1.0f; + float beta = 0.0f; + + int idx = 0; cl_int ret = CL_SUCCESS; - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, mGWS_M[b][0]); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, mGWS_M[b][1]); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, openCLBuffer(mSource.get())); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, openCLBuffer(mResource->mWeight.get())); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, openCLBuffer(mDest.get())); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, gemmWidth); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, gemmHeight); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, icC4); - ret |= mUnits[b * 3 + 1].kernel->get().setArg(index++, alpha * alpha); - MNN_CHECK_CL_SUCCESS(ret, "setArg ConvWinogradBuf SubGroup MatMul"); - mOpenCLBackend->recordKernel2d(mUnits[b * 3 + 1].kernel, mGWS_M[b], mLWS_M[b]); - mUnits[b * 3 + 1].globalWorkSize = {mGWS_M[b][0], mGWS_M[b][1]}; - mUnits[b * 3 + 1].localWorkSize = {mLWS_M[b][0], mLWS_M[b][1]}; + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, static_cast(e_pack)); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, static_cast(h_pack)); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, static_cast(l_pack)); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, alpha); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, beta); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, openCLBuffer(mSource.get())); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, e_pack); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, l_pack); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, openCLBuffer(mResource->mWeight.get())); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, h_pack); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, l_pack); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, openCLBuffer(mDest.get())); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, e_pack); + ret |= mUnits[b * 3 + 1].kernel->get().setArg(idx++, h_pack); + MNN_CHECK_CL_SUCCESS(ret, "setArg Winograd batchmatmul Kernel"); + + mOpenCLBackend->recordKernel3d(mUnits[b * 3 + 1].kernel, mGWS_M[b], mLWS_M[b]); + mUnits[b * 3 + 1].globalWorkSize = {mGWS_M[b][0], mGWS_M[b][1], mGWS_M[b][2]}; + mUnits[b * 3 + 1].localWorkSize = {mLWS_M[b][0], mLWS_M[b][1], mLWS_M[b][2]}; } // Dest Transform @@ -580,8 +630,10 @@ ErrorCode ConvBufWinograd::onEncode(const std::vector& inputs, const st ret |= mUnits[b * 3 + 2].kernel->get().setArg(index++, output->width()); ret |= mUnits[b * 3 + 2].kernel->get().setArg(index++, output->height()); ret |= mUnits[b * 3 + 2].kernel->get().setArg(index++, ocC4); + ret |= mUnits[b * 3 + 2].kernel->get().setArg(index++, M_pack); + ret |= mUnits[b * 3 + 2].kernel->get().setArg(index++, N_pack); ret |= mUnits[b * 3 + 2].kernel->get().setArg(index++, b); - MNN_CHECK_CL_SUCCESS(ret, "setArg ConvWinogradBuf SubGroup Dest Trans"); + MNN_CHECK_CL_SUCCESS(ret, "setArg ConvWinogradBuf Dest Trans"); std::string kernelName = "winoTransDstBuf"; mLWS_D[b] = localWS2DDefault(mGWS_D[b], mMaxWGS_D[b], mOpenCLBackend->getOpenCLRuntime(), kernelName + info, mUnits[b * 3 + 2].kernel).first; @@ -647,7 +699,7 @@ ErrorCode ConvBufWinograd::onExecute(const std::vector &inputs, const unit.globalWorkSize, unit.localWorkSize); #endif - MNN_CHECK_CL_SUCCESS(res, "While-gemm execute"); + MNN_CHECK_CL_SUCCESS(res, "Conv-Winograd execute"); } return NO_ERROR; } diff --git a/source/backend/opencl/execution/buffer/ConvBufWinograd.hpp b/source/backend/opencl/execution/buffer/ConvBufWinograd.hpp index 4cfe2abc7..e200fc2ef 100644 --- a/source/backend/opencl/execution/buffer/ConvBufWinograd.hpp +++ b/source/backend/opencl/execution/buffer/ConvBufWinograd.hpp @@ -39,6 +39,9 @@ class ConvBufWinograd : public CommonExecution { #ifdef MNN_SUPPORT_INTEL_SUBGROUP ErrorCode SubgroupOnResize(const std::vector &inputs, const std::vector &outputs); #endif /* MNN_SUPPORT_INTEL_SUBGROUP */ + +private: + void convertWeightFormat(cl::Buffer& buffer, const int tileK, const int tileN); private: OpenCLBackend* mOpenCLBackend; std::shared_ptr mResource; @@ -46,6 +49,8 @@ class ConvBufWinograd : public CommonExecution { int mKernelY; int mStrideX; int mStrideY; + int mCi; + int mCo; std::shared_ptr mSource; std::shared_ptr mDest; diff --git a/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp b/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp index 606e0bda4..4e541fc4c 100644 --- a/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp @@ -124,6 +124,7 @@ ErrorCode DepthwiseConvBufExecution::onEncode(const std::vector &input int kernelShape[2] = {filterHeight, filterWidth}; int dilationShape[2] = {mResource->mDilations[0], mResource->mDilations[1]}; + std::string info = std::to_string(inputChannels) + "_" + std::to_string(outputChannel) + "_" + std::to_string(filterHeight) + "_" + std::to_string(filterWidth) + "_" + std::to_string(mResource->mStrides[0]) + "_" + std::to_string(mResource->mStrides[1]) + "_" + std::to_string(mResource->mDilations[0]) + "_" + std::to_string(mResource->mDilations[1]); if(mStride_1) { // {"depthwise_conv2d_s1_c4h1w4", "depthwise_conv2d_s1_c8h1w4", "depthwise_conv2d_s1_c8h1w2"}; const int total_kernel = 3; @@ -183,7 +184,7 @@ ErrorCode DepthwiseConvBufExecution::onEncode(const std::vector &input MNN_CHECK_CL_SUCCESS(ret, "setArg DepthwiseConvBufExecution Stride_1 Kernel Select"); std::pair, int> retTune; - retTune = gws2dLwsTune(kernel[knl_idx], globalWorkSize[knl_idx], kernelName[knl_idx], maxWorkGroupSize); + retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); //printf("depthwiseCovs1 %d, %d\n", knl_idx, retTune.second); if(min_cost.first > retTune.second) { min_cost.first = retTune.second; @@ -259,7 +260,7 @@ ErrorCode DepthwiseConvBufExecution::onEncode(const std::vector &input MNN_CHECK_CL_SUCCESS(ret, "setArg DepthwiseConvBufExecution Kernel Select"); std::pair, int> retTune; - retTune = gws2dLwsTune(kernel[knl_idx], globalWorkSize[knl_idx], kernelName[knl_idx], maxWorkGroupSize); + retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); //printf("depthwiseCov!! %d, %d\n", knl_idx, retTune.second); if(min_cost.first > retTune.second) { min_cost.first = retTune.second; diff --git a/source/backend/opencl/execution/buffer/GroupNormBufExecution.cpp b/source/backend/opencl/execution/buffer/GroupNormBufExecution.cpp new file mode 100644 index 000000000..e2aaf0194 --- /dev/null +++ b/source/backend/opencl/execution/buffer/GroupNormBufExecution.cpp @@ -0,0 +1,267 @@ + +// +// GroupNormBufExecution.cpp +// MNN +// +// Created by MNN on 2024/06/24. +// Copyright © 2018, Alibaba Group Holding Limited +// +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE + +#include "backend/opencl/execution/buffer/GroupNormBufExecution.hpp" + +namespace MNN { +namespace OpenCL { + +GroupNormBufExecution::GroupNormBufExecution(const MNN::Op* op, Backend* backend) : CommonExecution(backend, op) { + auto group_norm_param = op->main_as_GroupNorm(); + mOpenCLBackend = static_cast(backend); + auto runtime = mOpenCLBackend->getOpenCLRuntime(); + mEpsilon = group_norm_param->epsilon(); + mBSwish = group_norm_param->bSwish(); + mGroup = group_norm_param->group(); + if (group_norm_param->gamma() && group_norm_param->beta()) { + auto bufferUnitSize = runtime->isSupportedFP16() ? sizeof(half_float::half) : sizeof(float); + + mHasGammaBeta = true; + int size = group_norm_param->gamma()->size(); + mGammaTensor.reset(Tensor::createDevice({ALIGN_UP4(size)})); + auto status = backend->onAcquireBuffer(mGammaTensor.get(), Backend::STATIC); + if (!status) { + MNN_ERROR("Out of memory when gamma is acquired in GroupNorm.\n"); + } + + cl::Buffer &gammaBuffer = openCLBuffer(mGammaTensor.get()); + + cl_int res; + auto GammaPtrCL = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer( + gammaBuffer, true, CL_MAP_WRITE, 0, ALIGN_UP4(size) * bufferUnitSize, nullptr, nullptr, &res); + if(GammaPtrCL != nullptr && res == CL_SUCCESS){ + if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()){ + for (int i = 0; i < size; i++) { + ((half_float::half*)GammaPtrCL)[i] = (half_float::half)(group_norm_param->gamma()->data()[i]); + } + for(int i=size; igamma()->data(), size * sizeof(float)); + } + } else { + MNN_ERROR("GroupNorm Gamma map error:%d\n", res); + } + + + if (group_norm_param->beta()->size() != size) { + MNN_ERROR("Size of gamma and beta are not match in GroupNorm.\n"); + } + mBetaTensor.reset(Tensor::createDevice({ALIGN_UP4(size)})); + status = backend->onAcquireBuffer(mBetaTensor.get(), Backend::STATIC); + if (!status) { + MNN_ERROR("Out of memory when beta is acquired in GroupNorm.\n"); + } + + cl::Buffer &betaBuffer = openCLBuffer(mBetaTensor.get()); + + auto BetaPtrCL = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer( + betaBuffer, true, CL_MAP_WRITE, 0, ALIGN_UP4(size) * bufferUnitSize, nullptr, nullptr, &res); + if(BetaPtrCL != nullptr && res == CL_SUCCESS){ + if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()){ + for (int i = 0; i < size; i++) { + ((half_float::half*)BetaPtrCL)[i] = (half_float::half)(group_norm_param->beta()->data()[i]); + } + for(int i=size; ibeta()->data(), size * sizeof(float)); + } + } else { + MNN_ERROR("GroupNorm Beta map error:%d\n", res); + } + } +} + +int GroupNormBufExecution::getLocalSize(int size, int maxGroupSize){ + int local_size = 1; + while(local_size * 2 <= maxGroupSize && local_size * 2 <= size){ + local_size *= 2; + } + return local_size; +} +ErrorCode GroupNormBufExecution::onEncode(const std::vector& inputs, const std::vector& outputs) { + auto runtime = static_cast(backend())->getOpenCLRuntime(); + + MNN_ASSERT(outputs.size() == 1); + auto input = inputs[0]; + auto output = outputs[0]; + MNN_ASSERT(input->dimensions() == 4); + MNN_ASSERT(output->dimensions() == 4); + mBatch = input->length(0); + if(inputs.size() > 1) { + MNN_ASSERT(inputs[1]->dimensions() == 2); + MNN_ASSERT(inputs[1]->length(0) == inputs[0]->length(0)); + MNN_ASSERT(inputs[1]->length(1) == inputs[0]->length(1)); + } + + size_t outter_size = mBatch * mGroup; + size_t inner_size = 1; + for (int i = 1; i < input->dimensions(); i++) { + inner_size *= inputs[0]->length(i); + } + inner_size /= mGroup; + + mUnits.clear(); + mUnits.resize(3); + std::vector inputShape = tensorShapeFormat(inputs[0]); + int inputWH[] = {inputShape[2], inputShape[1]}; + int region[] = {inputShape[0], UP_DIV(inputShape[3], 4), inputShape[1], inputShape[2]}; + + mInputPlain = std::make_shared(Tensor::createDevice(std::vector{inputShape[0] * inputShape[3] * ROUND_UP(inputShape[1] * inputShape[2], 4)})); + mOpenCLBackend->onAcquireBuffer(mInputPlain.get(), Backend::DYNAMIC); + mOutputPlain = std::make_shared(Tensor::createDevice(std::vector{inputShape[0] * inputShape[3] * ROUND_UP(inputShape[1] * inputShape[2], 4)})); + mOpenCLBackend->onAcquireBuffer(mOutputPlain.get(), Backend::DYNAMIC); + + mOpenCLBackend->onReleaseBuffer(mInputPlain.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(mOutputPlain.get(), Backend::DYNAMIC); + std::set buildOptions; + // convert nc4hw4 to nchw + { + auto &unit = mUnits[0]; + unit.kernel = runtime->buildKernel("buffer_convert_buf", "nc4hw4_buffer_to_nchw_buffer", {}, inputs[0], outputs[0]); + + mGWS = {(uint32_t)(UP_DIV(region[3] * region[1], 16) * 16), + (uint32_t)(UP_DIV(region[2] * region[0], 16) * 16)}; + mLWS = {16, 16}; + unit.globalWorkSize = {mGWS[0], mGWS[1]}; + unit.localWorkSize = {mLWS[0], mLWS[1]}; + + int global_dim0 = region[3] * region[1]; + int global_dim1 = region[2] * region[0]; + + //MNN_CHECK_CL_SUCCESS + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, global_dim0); + ret |= unit.kernel->get().setArg(idx++, global_dim1); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mInputPlain.get())); + ret |= unit.kernel->get().setArg(idx++, inputWH[1]); + ret |= unit.kernel->get().setArg(idx++, inputWH[0]); + ret |= unit.kernel->get().setArg(idx++, inputShape[3]); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(input)); + MNN_CHECK_CL_SUCCESS(ret, "setArg GroupNormBufExecution with group, convert nc4hw4 to nchw"); + + mOpenCLBackend->recordKernel2d(unit.kernel, mGWS, mLWS); + } + // do groupnorm + { + int area = inputWH[1] * inputWH[0]; + if(mHasGammaBeta){ + buildOptions.emplace("-DGAMMA_BETA"); + } + if(mBSwish) { + buildOptions.emplace("-DSWISH"); + } + if(area % 4 == 0) { + buildOptions.emplace("-DWH_4"); + } + if(inputs.size() > 1) { + buildOptions.emplace("-DDOUBLE_INPUTS"); + } + auto MaxLocalSize = std::min(runtime->getMaxWorkItemSizes()[0], (uint32_t)256); + + auto &unit = mUnits[1]; + std::string kernelName = "groupnorm_plain_buf"; + int local_size = getLocalSize(UP_DIV(inner_size, 4), MaxLocalSize); + buildOptions.emplace("-DLOCAL_SIZE=" + std::to_string(local_size)); + unit.kernel = runtime->buildKernel("groupnorm_buf", kernelName, buildOptions); + + mGWS = {static_cast(local_size), + static_cast(1), + static_cast(outter_size)}; + + mLWS = {static_cast(local_size), 1, 1}; + + unit.globalWorkSize = {mGWS[0], mGWS[1], mGWS[2]}; + unit.localWorkSize = {mLWS[0], mLWS[1], mLWS[2]}; + + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, mGWS[0]); + ret |= unit.kernel->get().setArg(idx++, mGWS[1]); + ret |= unit.kernel->get().setArg(idx++, mGWS[2]); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mInputPlain.get())); + if(inputs.size() > 1) { + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(inputs[1])); + } + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mOutputPlain.get())); + ret |= unit.kernel->get().setArg(idx++, static_cast(area)); + ret |= unit.kernel->get().setArg(idx++, static_cast(mGroup)); + ret |= unit.kernel->get().setArg(idx++, static_cast(inner_size)); + ret |= unit.kernel->get().setArg(idx++, static_cast(outter_size)); + if(mHasGammaBeta){ + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mGammaTensor.get())); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mBetaTensor.get())); + } + ret |= unit.kernel->get().setArg(idx++, mEpsilon); + MNN_CHECK_CL_SUCCESS(ret, "setArg GroupNormBufExecution with group, do group layernorm"); + mOpenCLBackend->recordKernel3d(unit.kernel, mGWS, mLWS); + } + // convert nchw to nc4hw4 + { + auto &unit = mUnits[2]; + + unit.kernel = runtime->buildKernel("buffer_convert_buf", "nchw_buffer_to_nc4hw4_buffer", {}, inputs[0], outputs[0]); + mLWS = {16, 16}; + mGWS = {(uint32_t)UP_DIV(region[3] * region[1], 16) * 16, + (uint32_t)UP_DIV(region[2] * region[0], 16) * 16}; + + unit.globalWorkSize = {mGWS[0], mGWS[1]}; + unit.localWorkSize = {mLWS[0], mLWS[1]}; + + int global_dim0 = region[3] * region[1]; + int global_dim1 = region[2] * region[0]; + + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, global_dim0); + ret |= unit.kernel->get().setArg(idx++, global_dim1); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mOutputPlain.get())); + ret |= unit.kernel->get().setArg(idx++, inputWH[1]); + ret |= unit.kernel->get().setArg(idx++, inputWH[0]); + ret |= unit.kernel->get().setArg(idx++, inputShape[3]); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(output)); + MNN_CHECK_CL_SUCCESS(ret, "setArg GroupNormBufExecution with group, convert nchw to nc4hw4"); + mOpenCLBackend->recordKernel2d(unit.kernel, mGWS, mLWS); + } + mOpenCLBackend->endRecord(mRecording); + + return NO_ERROR; + +} + + +class GroupNormBufCreator : public OpenCLBackend::Creator { +public: + virtual ~GroupNormBufCreator() = default; + virtual Execution *onCreate(const std::vector &inputs, const std::vector &outputs, + const MNN::Op *op, Backend *backend) const override { + for (int i = 0; i < inputs.size(); ++i) { + TensorUtils::setTensorSupportPack(inputs[i], false); + } + for (int i = 0; i < outputs.size(); ++i) { + TensorUtils::setTensorSupportPack(outputs[i], false); + } + + return new GroupNormBufExecution(op, backend); + } +}; + +REGISTER_OPENCL_OP_CREATOR(GroupNormBufCreator, OpType_GroupNorm, BUFFER); +} // namespace OpenCL +} // namespace MNN +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ +#endif/* MNN_OPENCL_BUFFER_CLOSED */ diff --git a/source/backend/opencl/execution/buffer/GroupNormBufExecution.hpp b/source/backend/opencl/execution/buffer/GroupNormBufExecution.hpp new file mode 100644 index 000000000..2f1ce8313 --- /dev/null +++ b/source/backend/opencl/execution/buffer/GroupNormBufExecution.hpp @@ -0,0 +1,45 @@ +// +// GroupNormBufExecution.hpp +// MNN +// +// Created by MNN on 2024/06/24. +// Copyright © 2018, Alibaba Group Holding Limited +// +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE + +#ifndef GroupNormBufExecution_hpp +#define GroupNormBufExecution_hpp + +#include "backend/opencl/execution/image/CommonExecution.hpp" + +namespace MNN { + +namespace OpenCL { +class GroupNormBufExecution : public CommonExecution { +public: + GroupNormBufExecution(const MNN::Op* op, Backend *backend); + virtual ~GroupNormBufExecution() = default; + + virtual ErrorCode onEncode(const std::vector &inputs, const std::vector &outputs) override; +private: + int getLocalSize(int size, int maxGroupSize); +private: + OpenCLBackend *mOpenCLBackend; + float mEpsilon{}; + int32_t mBSwish{}; + int32_t mGroup = 32; + int32_t mBatch; + std::unique_ptr mGammaTensor; + std::unique_ptr mBetaTensor; + std::shared_ptr mInputPlain, mOutputPlain; + bool mHasGammaBeta = false; + std::vector mLWS{0, 0, 0, 0}; + std::vector mGWS{0, 0, 0, 0}; +}; + +} // namespace OPENCL +} // namespace MNN +#endif /* GroupNormBufExecution_hpp */ +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ +#endif diff --git a/source/backend/opencl/execution/buffer/LoopBufExecution.cpp b/source/backend/opencl/execution/buffer/LoopBufExecution.cpp index 55a624f78..9935db7df 100644 --- a/source/backend/opencl/execution/buffer/LoopBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/LoopBufExecution.cpp @@ -27,9 +27,19 @@ static void _TileOrPackTensor(Tensor *input, Tensor *output, std::shared_ptrgetOpenCLRuntime()->getGpuType() == GpuType::ADRENO) { buildOptions.emplace("-DUSE_CL_MAD=1"); @@ -530,47 +559,41 @@ ErrorCode LoopBatchMatMulBufExecution::onEncode(const std::vector &inp buildOptions.emplace(" -DPRECISION=32"); } - int localM = MDIMC; - int localN = NDIMC; + Unit unit; + unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("matmul_params_buf", "XgemmBatched", buildOptions); + + int out_per_thread_m = tileM / localM; + int out_per_thread_n = tileN / localN; + + std::vector globalWorkSize = {static_cast(e_pack/out_per_thread_m), static_cast(h_pack/out_per_thread_n), static_cast(n)}; + std::vector localWorkSize = {static_cast(localM), static_cast(localN), 1}; + + float alpha = 1.0; + float beta = 0.0f; + + int idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, static_cast(e_pack)); + ret |= unit.kernel->get().setArg(idx++, static_cast(h_pack)); + ret |= unit.kernel->get().setArg(idx++, static_cast(l_pack)); + ret |= unit.kernel->get().setArg(idx++, alpha); + ret |= unit.kernel->get().setArg(idx++, beta); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mTmpTensors[1].get())); + ret |= unit.kernel->get().setArg(idx++, e_pack); + ret |= unit.kernel->get().setArg(idx++, l_pack); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mTmpTensors[2].get())); + ret |= unit.kernel->get().setArg(idx++, h_pack); + ret |= unit.kernel->get().setArg(idx++, l_pack); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mTmpTensors[0].get())); + ret |= unit.kernel->get().setArg(idx++, e_pack); + ret |= unit.kernel->get().setArg(idx++, h_pack); + MNN_CHECK_CL_SUCCESS(ret, "setArg LoopBuf GemmTile Kernel"); + + unit.globalWorkSize = {globalWorkSize[0], globalWorkSize[1], globalWorkSize[2]}; + unit.localWorkSize = {localWorkSize[0], localWorkSize[1], localWorkSize[2]}; + mUnits.emplace_back(unit); + mOpenCLBackend->recordKernel3d(unit.kernel, globalWorkSize, localWorkSize); - for(int b = 0; b < n; b++) { - Unit unit; - unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("matmul_params_buf", "Xgemm", buildOptions); - - int out_per_thread_m = tileM / localM; - int out_per_thread_n = tileN / localN; - - std::vector globalWorkSize = {static_cast(e_pack/out_per_thread_m), static_cast(h_pack/out_per_thread_n)}; - std::vector localWorkSize = {static_cast(localM), static_cast(localN)}; - - float alpha = 1.0; - float beta = 0.0f; - // A: [n, l, e] - // B: [n, l, h] - int offset_a = b * l_pack * e_pack; - int offset_b = b * l_pack * h_pack; - int offset_c = b * e_pack * h_pack; - - int idx = 0; - cl_int ret = CL_SUCCESS; - ret |= unit.kernel->get().setArg(idx++, static_cast(e_pack)); - ret |= unit.kernel->get().setArg(idx++, static_cast(h_pack)); - ret |= unit.kernel->get().setArg(idx++, static_cast(l_pack)); - ret |= unit.kernel->get().setArg(idx++, alpha); - ret |= unit.kernel->get().setArg(idx++, beta); - ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mTmpTensors[1].get())); - ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mTmpTensors[2].get())); - ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mTmpTensors[0].get())); - ret |= unit.kernel->get().setArg(idx++, offset_a); - ret |= unit.kernel->get().setArg(idx++, offset_b); - ret |= unit.kernel->get().setArg(idx++, offset_c); - MNN_CHECK_CL_SUCCESS(ret, "setArg LoopBuf GemmTile Kernel"); - - unit.globalWorkSize = {globalWorkSize[0], globalWorkSize[1]}; - unit.localWorkSize = {localWorkSize[0], localWorkSize[1]}; - mUnits.emplace_back(unit); - mOpenCLBackend->recordKernel2d(unit.kernel, globalWorkSize, localWorkSize); - } } else { // matmul mTmpTensors[0] = std::make_shared(Tensor::createDevice(std::vector{1, n, e, h}, Tensor::CAFFE)); @@ -701,7 +724,7 @@ ErrorCode LoopBatchMatMulBufExecution::onExecute(const std::vector &in std::string name = "While-gemm"; if(mBatchGemmOpt) { - if(idx <= mUnits.size()-2 && idx >= mUnits.size()-1-mBatch) { + if(idx == 2) { name += "-batchgemm"; } else if(idx == 0) { name += "-rearrangeA"; @@ -755,18 +778,16 @@ ErrorCode LoopBinaryBufExecution::onEncode(const std::vector &inputs, Unit unit; auto input0 = mTensors[cmd->indexes()->data()[1]]; - std::vector Input0Shape = tensorShapeFormat(input0); - int Input0Size[4] = {Input0Shape.at(2), Input0Shape.at(1),Input0Shape.at(3),Input0Shape.at(0)}; + std::vector input0C4Shape = tensorShapeFormat(input0); + int input0C4Size[4] = {input0C4Shape.at(0), input0C4Shape.at(3),input0C4Shape.at(1),input0C4Shape.at(2)}; auto input1 = mTensors[cmd->indexes()->data()[2]]; - std::vector Input1Shape = tensorShapeFormat(input1); - int Input1Size[4] = {Input1Shape.at(2), Input1Shape.at(1),Input1Shape.at(3),Input1Shape.at(0)}; + std::vector input1C4Shape = tensorShapeFormat(input1); + int input1C4Size[4] = {input1C4Shape.at(0), input1C4Shape.at(3),input1C4Shape.at(1),input1C4Shape.at(2)}; auto output = mTensors[cmd->indexes()->data()[0]]; - std::vector Shape = tensorShapeFormat(output); + std::vector outputC4Shape = tensorShapeFormat(output); - bool broadcastInput0 = false; - bool broadcastInput1 = false; int input0Shape[8] = {1, 1, 1, 1, 1, 1, 1, 1}; int input1Shape[8] = {1, 1, 1, 1, 1, 1, 1, 1}; int outputShape[8] = {1, 1, 1, 1, 1, 1, 1, 1}; @@ -831,25 +852,36 @@ ErrorCode LoopBinaryBufExecution::onEncode(const std::vector &inputs, if(input1->dimensions() > 4) { - for(int i = 4; i < input1->dimensions(); i++) + for(int i = 4; i < output->dimensions(); i++) { iC *= outputShape[i]; } } - input1Shape[0] = iN; + outputShape[0] = iN; outputShape[1] = iC; outputShape[2] = iH; outputShape[3] = iW; outputShape[4] = 1; } - - const int Channel = Shape.at(3); - const int Width = Shape.at(2); - const int Height = Shape.at(1); - const int Batch = Shape.at(0); - const int ChannelBlock = UP_DIV(Channel, 4); auto BuildOptions = mBuildOptions; + for(int i = 0; i < 4; ++i){ + if(input1C4Shape[i] != outputC4Shape[i]){ + BuildOptions.emplace("-DBROADCAST_INPUT1"); + break; + } + } + + const int Channel = outputC4Shape.at(3); + const int Width = outputC4Shape.at(2); + const int Height = outputC4Shape.at(1); + const int Batch = outputC4Shape.at(0); + const int ChannelBlock = UP_DIV(Channel, 4); std::string KernelName = "broadcast_binary_buf"; + if(input0Shape[1] == input1Shape[1] && input0C4Size[1] == input1C4Size[1]){ + KernelName = "broadcast_binary_channel_equall_buf"; + } else if((input0->dimensions() == 1 && input0Shape[1] == 1) || (input1->dimensions() == 1 && input1Shape[1] == 1)){ + KernelName = "broadcast_binary_dimmision1_channel1_buf"; + } unit.kernel = runTime->buildKernel("loop_buf", KernelName, BuildOptions, input0, output); uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(unit.kernel)); @@ -864,9 +896,9 @@ ErrorCode LoopBinaryBufExecution::onEncode(const std::vector &inputs, ret |= unit.kernel->get().setArg(index++, openCLBuffer(input0)); ret |= unit.kernel->get().setArg(index++, openCLBuffer(input1)); ret |= unit.kernel->get().setArg(index++, sizeof(input0Shape), input0Shape); - ret |= unit.kernel->get().setArg(index++, sizeof(Input0Size), Input0Size); + ret |= unit.kernel->get().setArg(index++, sizeof(input0C4Size), input0C4Size); ret |= unit.kernel->get().setArg(index++, sizeof(input1Shape), input1Shape); - ret |= unit.kernel->get().setArg(index++, sizeof(Input1Size), Input1Size); + ret |= unit.kernel->get().setArg(index++, sizeof(input1C4Size), input1C4Size); ret |= unit.kernel->get().setArg(index++, sizeof(outputShape), outputShape); ret |= unit.kernel->get().setArg(index++, Width); ret |= unit.kernel->get().setArg(index++, Height); diff --git a/source/backend/opencl/execution/buffer/SelfAttentionBufExecution.cpp b/source/backend/opencl/execution/buffer/SelfAttentionBufExecution.cpp new file mode 100644 index 000000000..dc21fcb68 --- /dev/null +++ b/source/backend/opencl/execution/buffer/SelfAttentionBufExecution.cpp @@ -0,0 +1,586 @@ +// +// FmhaV2Execution.cpp +// MNN +// +// Created by MNN on 2024/06/03. +// Copyright © 2018, Alibaba Group Holding Limited +// +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE + +#include +#include +#include "backend/opencl/execution/buffer/SelfAttentionBufExecution.hpp" + +namespace MNN { +namespace OpenCL { + +SelfAttentionBufImpl::SelfAttentionBufImpl(const MNN::Op *op, Backend *backend){ + auto fmha_v2_param = op->main_as_FmhaV2Param(); + mNumHead = fmha_v2_param->heads(); + mOpenCLBackend = static_cast(backend); + auto kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("self_attention_buf", "softmax_inside", {"-DSOFTMAX_LOCAL_SIZE=512"}); + mMaxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(kernel)); +} + +int SelfAttentionBufImpl::getLocalSize(int size, int maxGroupSize){ + int local_size = 1; + while(local_size * 2 <= maxGroupSize && local_size * 2 <= size){ + local_size *= 2; + } + return local_size; +} +// [B, seqlen, HeadNum*3*HeadDim] -> [B, seqlen, HeadNum*HeadDim] +ErrorCode SelfAttentionBufImpl::onResize(Backend *backend, const std::vector &inputs, const std::vector &outputs) { + mOpenCLBackend = static_cast(backend); + mOpenCLBackend->startRecord(mRecording); + + auto input = inputs[0];// [Batch, seqLen, mNumHead * 3 * mHeadDim] + + auto runtime = mOpenCLBackend->getOpenCLRuntime(); + auto shape = input->shape(); + + int tile_mn = 32; + int tile_k = 16; // for gemm alignment + int batch = shape[0]; + int seq_len = shape[1]; + mHeadDim = shape[2] / mNumHead / 3; + mScale = 1.0 / sqrt(mHeadDim); + + if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()){ + mByte = 2; + } + + // split several pieces for memory save + if(seq_len > 1024) { + mQseqSplitNum = (seq_len >= 4096) ? 8 : ((seq_len < 2048) ? 2 : 4); + } + int buffer_size = batch * mNumHead * ROUND_UP(mHeadDim, tile_k) * ROUND_UP(seq_len, tile_mn); + int buffer_qk_size = batch * mNumHead * ROUND_UP(seq_len, tile_mn) * ROUND_UP(seq_len, tile_mn) / mQseqSplitNum; + int buffer_v_size = batch * mNumHead * ROUND_UP(mHeadDim, tile_mn) * ROUND_UP(seq_len, tile_mn); + mTempQ.reset(Tensor::createDevice(std::vector{buffer_size / mQseqSplitNum})); + mTempK.reset(Tensor::createDevice(std::vector{buffer_size})); + mTempV.reset(Tensor::createDevice(std::vector{buffer_v_size})); + mTempQK.reset(Tensor::createDevice(std::vector{buffer_qk_size})); + mTempTrans.reset(Tensor::createDevice(std::vector{buffer_qk_size})); + mTempSoftMax.reset(Tensor::createDevice(std::vector{buffer_qk_size})); + mTempQKV.reset(Tensor::createDevice(std::vector{buffer_v_size / mQseqSplitNum})); + +// printf("buffer size x2:%f MB, buffer qk size x3:%f MB, buffer v size x2 :%f MB\n", buffer_size * 2.0 / 1024.0 / 1024.0, buffer_qk_size * 2.0 / 1024.0 / 1024.0, buffer_v_size * 2.0 / 1024.0 / 1024.0); + mOpenCLBackend->onAcquireBuffer(mTempQ.get(), Backend::DYNAMIC); + mOpenCLBackend->onAcquireBuffer(mTempK.get(), Backend::DYNAMIC); + mOpenCLBackend->onAcquireBuffer(mTempV.get(), Backend::DYNAMIC); + mOpenCLBackend->onAcquireBuffer(mTempQK.get(), Backend::DYNAMIC); + + mOpenCLBackend->onReleaseBuffer(mTempQ.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(mTempK.get(), Backend::DYNAMIC); + + mOpenCLBackend->onAcquireBuffer(mTempSoftMax.get(), Backend::DYNAMIC); + + mOpenCLBackend->onReleaseBuffer(mTempQK.get(), Backend::DYNAMIC); + mOpenCLBackend->onAcquireBuffer(mTempTrans.get(), Backend::DYNAMIC); + + mOpenCLBackend->onReleaseBuffer(mTempSoftMax.get(), Backend::DYNAMIC); + mOpenCLBackend->onAcquireBuffer(mTempQKV.get(), Backend::DYNAMIC); + + + mOpenCLBackend->onReleaseBuffer(mTempV.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(mTempTrans.get(), Backend::DYNAMIC); + mOpenCLBackend->onReleaseBuffer(mTempQKV.get(), Backend::DYNAMIC); + + mKernel_split.resize(mQseqSplitNum); + mKernel_qk.resize(mQseqSplitNum); + mKernel_softmax.resize(mQseqSplitNum); + mKernel_qkv.resize(mQseqSplitNum); + mKernel_clip.resize(mQseqSplitNum); + mKernel_trans.resize(mQseqSplitNum); + mGlobalWorkSizeSplit.resize(mQseqSplitNum); + mLocalWorkSizeSplit.resize(mQseqSplitNum); + mGlobalWorkSizeClip.resize(mQseqSplitNum); + mLocalWorkSizeClip.resize(mQseqSplitNum); + mGlobalWorkSizeQk.resize(mQseqSplitNum); + mLocalWorkSizeQk.resize(mQseqSplitNum); + mGlobalWorkSizeSoftMax.resize(mQseqSplitNum); + mLocalWorkSizeSoftMax.resize(mQseqSplitNum); + mGlobalWorkSizeQkv.resize(mQseqSplitNum); + mLocalWorkSizeQkv.resize(mQseqSplitNum); + mGlobalWorkSizeTrans.resize(mQseqSplitNum); + mLocalWorkSizeTrans.resize(mQseqSplitNum); + + for(int seq_idx = 0; seq_idx < mQseqSplitNum; seq_idx++) { + // Split input to q k v + { + // [Batch, seqLen, mNumHead * 3 * mHeadDim] -> + // Q : [Batch * mNumHead, ROUND_UP(mHeadDim, tile_k), ROUND_UP(seqLen, tile_mn)] + // K : [Batch * mNumHead, ROUND_UP(mHeadDim, tile_k), ROUND_UP(seqLen, tile_mn)] + // V : [Batch * mNumHead, ROUND_UP(seqLen, tile_mn), ROUND_UP(mHeadDim, tile_mn)] + std::set buildOption; + if((mHeadDim % 4) != 0){ + buildOption.emplace("-DHEADDIM_LEAVE"); + } + if((seq_len % 4) != 0){ + buildOption.emplace("-DSEQLEN_LEAVE"); + } + + int seq_len_pack_mn = ROUND_UP(seq_len, tile_mn); + int head_dim_pack_mn = ROUND_UP(mHeadDim, tile_mn); + int head_dim_pack_k = ROUND_UP(mHeadDim, tile_k); + int seq_len_piece = seq_len_pack_mn/mQseqSplitNum; + + mKernel_split[seq_idx] = runtime->buildKernel("self_attention_buf", "split_transpose_qkv", buildOption, inputs[0], outputs[0]); + auto maxWorkGroupSize = static_cast(runtime->getMaxWorkGroupSize(mKernel_split[seq_idx])); + + mGlobalWorkSizeSplit[seq_idx] = {static_cast(UP_DIV(seq_len_pack_mn, 4)), static_cast(UP_DIV(head_dim_pack_mn, 4)), static_cast(batch*mNumHead)}; + + if(seq_idx > 0) { + mGlobalWorkSizeSplit[seq_idx][0] = static_cast(UP_DIV(seq_len_piece, 4)); + } + uint32_t index = 0; + cl_int ret = CL_SUCCESS; + ret |= mKernel_split[seq_idx]->get().setArg(index++, mGlobalWorkSizeSplit[seq_idx][0]); + ret |= mKernel_split[seq_idx]->get().setArg(index++, mGlobalWorkSizeSplit[seq_idx][1]); + ret |= mKernel_split[seq_idx]->get().setArg(index++, mGlobalWorkSizeSplit[seq_idx][2]); + ret |= mKernel_split[seq_idx]->get().setArg(index++, openCLBuffer(input)); + ret |= mKernel_split[seq_idx]->get().setArg(index++, openCLBuffer(mTempQ.get())); + ret |= mKernel_split[seq_idx]->get().setArg(index++, openCLBuffer(mTempK.get())); + ret |= mKernel_split[seq_idx]->get().setArg(index++, openCLBuffer(mTempV.get())); + ret |= mKernel_split[seq_idx]->get().setArg(index++, seq_len_pack_mn); + ret |= mKernel_split[seq_idx]->get().setArg(index++, seq_len_piece); + ret |= mKernel_split[seq_idx]->get().setArg(index++, head_dim_pack_mn); + ret |= mKernel_split[seq_idx]->get().setArg(index++, head_dim_pack_k); + ret |= mKernel_split[seq_idx]->get().setArg(index++, seq_len); + ret |= mKernel_split[seq_idx]->get().setArg(index++, mNumHead); + ret |= mKernel_split[seq_idx]->get().setArg(index++, mHeadDim); + ret |= mKernel_split[seq_idx]->get().setArg(index++, seq_idx); + MNN_CHECK_CL_SUCCESS(ret, "setArg split_transpose_qkv"); + mLocalWorkSizeSplit[seq_idx] = localWS3DDefault(mGlobalWorkSizeSplit[seq_idx], maxWorkGroupSize, runtime, "split_transpose_qkv", mKernel_split[seq_idx]).first; + + mOpenCLBackend->recordKernel3d(mKernel_split[seq_idx], mGlobalWorkSizeSplit[seq_idx], mLocalWorkSizeSplit[seq_idx]); + } + + // query * key -> div + { + // Q : [Batch * mNumHead, ROUND_UP(mHeadDim, tile_k), ROUND_UP(seqLen, tile_mn)] -> [B, K, M] + // K : [Batch * mNumHead, ROUND_UP(mHeadDim, tile_k), ROUND_UP(seqLen, tile_mn)] -> [B, K, N] + // QV: [Batch * mNumHead, ROUND_UP(seqLen, tile_mn), ROUND_UP(seqLen, tile_mn)] -> [B, N, M] + int loop = batch * mNumHead; + int e_pack = ROUND_UP(seq_len, tile_mn) / mQseqSplitNum; + int l_pack = ROUND_UP(mHeadDim, tile_k); + int h_pack = ROUND_UP(seq_len, tile_mn); + + std::set buildOptions; + + uint32_t layout = 4; + auto param = getGemmParams({(uint32_t)e_pack, (uint32_t)h_pack, (uint32_t)l_pack, layout, (uint32_t)loop}, {openCLBuffer(mTempQ.get()), openCLBuffer(mTempK.get()), openCLBuffer(mTempQK.get())}, mOpenCLBackend->getOpenCLRuntime()); + + int GEMMK=param[0], KREG=param[1], KWG=param[2], KWI=param[3], MDIMA=param[4], MDIMC=param[5], MWG=param[6], NDIMB=param[7], NDIMC=param[8], NWG=param[9], SA=param[10], SB=param[11], STRM=param[12], STRN=param[13], VWM=param[14], VWN=param[15]; + buildOptions.emplace("-DGEMMK=" + std::to_string(GEMMK)); + buildOptions.emplace("-DKREG=" + std::to_string(KREG)); + buildOptions.emplace("-DKWG=" + std::to_string(KWG)); + buildOptions.emplace("-DKWI=" + std::to_string(KWI)); + buildOptions.emplace("-DMDIMA=" + std::to_string(MDIMA)); + buildOptions.emplace("-DMDIMC=" + std::to_string(MDIMC)); + buildOptions.emplace("-DMWG=" + std::to_string(MWG)); + buildOptions.emplace("-DNDIMB=" + std::to_string(NDIMB)); + buildOptions.emplace("-DNDIMC=" + std::to_string(NDIMC)); + buildOptions.emplace("-DNWG=" + std::to_string(NWG)); + buildOptions.emplace("-DSA=" + std::to_string(SA)); + buildOptions.emplace("-DSB=" + std::to_string(SB)); + buildOptions.emplace("-DSTRM=" + std::to_string(STRM)); + buildOptions.emplace("-DSTRN=" + std::to_string(STRN)); + buildOptions.emplace("-DVWM=" + std::to_string(VWM)); + buildOptions.emplace("-DVWN=" + std::to_string(VWN)); + if(layout >= 4) { + buildOptions.emplace("-DOUTPUTMN"); + } + + int tileM = MWG; + int tileN = NWG; + int localM = MDIMC; + int localN = NDIMC; + + if(mOpenCLBackend->getOpenCLRuntime()->getGpuType() == GpuType::ADRENO) { + buildOptions.emplace("-DUSE_CL_MAD=1"); + buildOptions.emplace("-DRELAX_WORKGROUP_SIZE=1"); + } + + if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()){ + buildOptions.emplace(" -DPRECISION=16"); + } else { + buildOptions.emplace(" -DPRECISION=32"); + } + + mKernel_qk[seq_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("matmul_params_buf", "XgemmBatched", buildOptions); + + int out_per_thread_m = tileM / localM; + int out_per_thread_n = tileN / localN; + + mGlobalWorkSizeQk[seq_idx] = {static_cast(e_pack/out_per_thread_m), static_cast(h_pack/out_per_thread_n), static_cast(loop)}; + mLocalWorkSizeQk[seq_idx] = {static_cast(localM), static_cast(localN), 1}; + + float alpha = mScale; + float beta = 0.0f; + + int idx = 0; + cl_int ret = CL_SUCCESS; + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, static_cast(e_pack)); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, static_cast(h_pack)); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, static_cast(l_pack)); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, alpha); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, beta); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, openCLBuffer(mTempQ.get())); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, e_pack); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, l_pack); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, openCLBuffer(mTempK.get())); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, h_pack); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, l_pack); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, openCLBuffer(mTempQK.get())); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, e_pack); + ret |= mKernel_qk[seq_idx]->get().setArg(idx++, h_pack); + MNN_CHECK_CL_SUCCESS(ret, "setArg Self-Attention batchmatmul qk Kernel"); + mOpenCLBackend->recordKernel3d(mKernel_qk[seq_idx], mGlobalWorkSizeQk[seq_idx], mLocalWorkSizeQk[seq_idx]); + + } + + // softmax + { + // QV: [Batch * mNumHead, ROUND_UP(seqLen, tile_mn), ROUND_UP(seqLen, tile_mn)] + // Sotmax: [Batch * mNumHead, ROUND_UP(seqLen, tile_mn), ROUND_UP(seqLen, tile_mn)] + // axis : 1 (middle dim) + mSoftmaxShape[0] = batch*mNumHead; + mSoftmaxShape[1] = ROUND_UP(seq_len, tile_mn)/mQseqSplitNum; + mSoftmaxShape[2] = ROUND_UP(seq_len, tile_mn); + + auto MaxLocalSize = std::min(std::min(runtime->getMaxWorkItemSizes()[0], mMaxWorkGroupSize), static_cast(256)); + int localSize = getLocalSize(mSoftmaxShape[1], MaxLocalSize); + if(localSize < 4){ + localSize = 1; + } + + std::set buildOption; + buildOption.emplace("-DSOFTMAX_LOCAL_SIZE=" + std::to_string(localSize)); + // buildOption.emplace("-DOUTPUT_TRANSPOSE"); + + mKernel_softmax[seq_idx] = runtime->buildKernel("self_attention_buf", "softmax_inside", buildOption, inputs[0], outputs[0]); + mGlobalWorkSizeSoftMax[seq_idx] = {static_cast(localSize), static_cast(mSoftmaxShape[1]), static_cast(mSoftmaxShape[0])}; + + uint32_t index = 0; + cl_int ret = CL_SUCCESS; + ret |= mKernel_softmax[seq_idx]->get().setArg(index++, mGlobalWorkSizeSoftMax[seq_idx][0]); + ret |= mKernel_softmax[seq_idx]->get().setArg(index++, mGlobalWorkSizeSoftMax[seq_idx][1]); + ret |= mKernel_softmax[seq_idx]->get().setArg(index++, mGlobalWorkSizeSoftMax[seq_idx][2]); + ret |= mKernel_softmax[seq_idx]->get().setArg(index++, openCLBuffer(mTempQK.get())); + ret |= mKernel_softmax[seq_idx]->get().setArg(index++, openCLBuffer(mTempSoftMax.get())); + ret |= mKernel_softmax[seq_idx]->get().setArg(index++, seq_len); + ret |= mKernel_softmax[seq_idx]->get().setArg(index++, mSoftmaxShape); + MNN_CHECK_CL_SUCCESS(ret, "setArg Self-Attention softmax"); + + mLocalWorkSizeSoftMax[seq_idx] = {static_cast(localSize), 1, 1}; + mOpenCLBackend->recordKernel3d(mKernel_softmax[seq_idx], mGlobalWorkSizeSoftMax[seq_idx], mLocalWorkSizeSoftMax[seq_idx]); + } + + { + unsigned int tileW = 32; + unsigned int tileH = 32; + int loop = batch * mNumHead; + int transDimW = ROUND_UP(seq_len, tile_mn) / mQseqSplitNum; + int transDimH = ROUND_UP(seq_len, tile_mn); + if((transDimW & 63) == 0 && (transDimH & 63) == 0) { + tileW = 64; + tileH = 64; + } + unsigned int localW = 8; + unsigned int localH = 8; + std::set buildOptions; + buildOptions.emplace("-DWGSW=" + std::to_string(tileW)); + buildOptions.emplace("-DWGSH=" + std::to_string(tileH)); + buildOptions.emplace("-DTSW=" + std::to_string(tileW/localW)); + buildOptions.emplace("-DTSH=" + std::to_string(tileH/localH)); + + mKernel_trans[seq_idx] = runtime->buildKernel("self_attention_buf", "trans_3d_buf", buildOptions, inputs[0], outputs[0]); + + int w_per_thread = tileW / localW; + int h_per_thread = tileH / localH; + mGlobalWorkSizeTrans[seq_idx] = {(uint32_t)transDimW/w_per_thread, (uint32_t)transDimH/h_per_thread, (uint32_t)(loop)}; + mLocalWorkSizeTrans[seq_idx] = {localW, localH, 1}; + + uint32_t index = 0; + cl_int ret = CL_SUCCESS; + ret |= mKernel_trans[seq_idx]->get().setArg(index++, openCLBuffer(mTempSoftMax.get())); + ret |= mKernel_trans[seq_idx]->get().setArg(index++, openCLBuffer(mTempTrans.get())); + ret |= mKernel_trans[seq_idx]->get().setArg(index++, loop); + ret |= mKernel_trans[seq_idx]->get().setArg(index++, transDimW); + ret |= mKernel_trans[seq_idx]->get().setArg(index++, transDimH); + MNN_CHECK_CL_SUCCESS(ret, "setArg Self-Attention transpose"); + + mOpenCLBackend->recordKernel3d(mKernel_trans[seq_idx], mGlobalWorkSizeTrans[seq_idx], mLocalWorkSizeTrans[seq_idx]); + } + + + // qk * value + { + // Sotmax: [Batch * mNumHead, ROUND_UP(seqLen, tile), ROUND_UP(seqLen, tile)] -> [B, K, M] + // V : [Batch * mNumHead, ROUND_UP(seqLen, tile), ROUND_UP(mHeadDim, tile)] -> [B, K, N] + // QKV : [Batch * mNumHead, ROUND_UP(mHeadDim, tile), ROUND_UP(seqLen, tile)] -> [B, N, M] + + int loop = batch * mNumHead; + int e_pack = ROUND_UP(seq_len, tile_mn) / mQseqSplitNum; + int l_pack = ROUND_UP(seq_len, tile_mn); + int h_pack = ROUND_UP(mHeadDim, tile_mn); + + std::set buildOptions; + /* + 0 -> A:[K, M] B:[K, N] C:[N, M] + 1 -> A:[K, M] B:[N, K] C:[N, M] + 2 -> A:[M, K] B:[K, N] C:[N, M] + 3 -> A:[M, K] B:[N, K] C:[N, M] + 4 -> A:[K, M] B:[K, N] C:[M, N] + 5 -> A:[K, M] B:[N, K] C:[M, N] + 6 -> A:[M, K] B:[K, N] C:[M, N] + 7 -> A:[M, K] B:[N, K] C:[M, N] + */ + uint32_t layout = 0; + auto param = getGemmParams({(uint32_t)e_pack, (uint32_t)h_pack, (uint32_t)l_pack, layout, (uint32_t)loop}, {openCLBuffer(mTempTrans.get()), openCLBuffer(mTempV.get()), openCLBuffer(mTempQKV.get())}, mOpenCLBackend->getOpenCLRuntime()); + + int GEMMK=param[0], KREG=param[1], KWG=param[2], KWI=param[3], MDIMA=param[4], MDIMC=param[5], MWG=param[6], NDIMB=param[7], NDIMC=param[8], NWG=param[9], SA=param[10], SB=param[11], STRM=param[12], STRN=param[13], VWM=param[14], VWN=param[15]; + buildOptions.emplace("-DGEMMK=" + std::to_string(GEMMK)); + buildOptions.emplace("-DKREG=" + std::to_string(KREG)); + buildOptions.emplace("-DKWG=" + std::to_string(KWG)); + buildOptions.emplace("-DKWI=" + std::to_string(KWI)); + buildOptions.emplace("-DMDIMA=" + std::to_string(MDIMA)); + buildOptions.emplace("-DMDIMC=" + std::to_string(MDIMC)); + buildOptions.emplace("-DMWG=" + std::to_string(MWG)); + buildOptions.emplace("-DNDIMB=" + std::to_string(NDIMB)); + buildOptions.emplace("-DNDIMC=" + std::to_string(NDIMC)); + buildOptions.emplace("-DNWG=" + std::to_string(NWG)); + buildOptions.emplace("-DSA=" + std::to_string(SA)); + buildOptions.emplace("-DSB=" + std::to_string(SB)); + buildOptions.emplace("-DSTRM=" + std::to_string(STRM)); + buildOptions.emplace("-DSTRN=" + std::to_string(STRN)); + buildOptions.emplace("-DVWM=" + std::to_string(VWM)); + buildOptions.emplace("-DVWN=" + std::to_string(VWN)); + if(layout >= 4) { + buildOptions.emplace("-DOUTPUTMN"); + } + + int tileM = MWG; + int tileN = NWG; + int localM = MDIMC; + int localN = NDIMC; + + if(mOpenCLBackend->getOpenCLRuntime()->getGpuType() == GpuType::ADRENO) { + buildOptions.emplace("-DUSE_CL_MAD=1"); + buildOptions.emplace("-DRELAX_WORKGROUP_SIZE=1"); + } + + if(mOpenCLBackend->getOpenCLRuntime()->isSupportedFP16()){ + buildOptions.emplace(" -DPRECISION=16"); + } else { + buildOptions.emplace(" -DPRECISION=32"); + } + + mKernel_qkv[seq_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("matmul_params_buf", "XgemmBatched", buildOptions); + + int out_per_thread_m = tileM / localM; + int out_per_thread_n = tileN / localN; + + mGlobalWorkSizeQkv[seq_idx] = {static_cast(e_pack/out_per_thread_m), static_cast(h_pack/out_per_thread_n), static_cast(loop)}; + mLocalWorkSizeQkv[seq_idx] = {static_cast(localM), static_cast(localN), 1}; + + float alpha = 1.0f; + float beta = 0.0f; + + int idx = 0; + cl_int ret = CL_SUCCESS; + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, static_cast(e_pack)); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, static_cast(h_pack)); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, static_cast(l_pack)); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, alpha); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, beta); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, openCLBuffer(mTempTrans.get())); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, e_pack); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, l_pack); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, openCLBuffer(mTempV.get())); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, h_pack); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, l_pack); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, openCLBuffer(mTempQKV.get())); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, e_pack); + ret |= mKernel_qkv[seq_idx]->get().setArg(idx++, h_pack); + MNN_CHECK_CL_SUCCESS(ret, "setArg Self-Attention batchmatmul qkv Kernel"); + mOpenCLBackend->recordKernel3d(mKernel_qkv[seq_idx], mGlobalWorkSizeQkv[seq_idx], mLocalWorkSizeQkv[seq_idx]); + } + + // transpose to output + { + // QKV : [Batch * mNumHead, ROUND_UP(mHeadDim, tile_mn), ROUND_UP(seqLen, tile_mn)] -> [B, N, M] + // output: [Batch, seqLen, mNumHead * mHeadDim] + std::set buildOption; + + mKernel_clip[seq_idx] = runtime->buildKernel("self_attention_buf", "clip_transpose_qkv", buildOption, inputs[0], outputs[0]); + auto maxWorkGroupSize = static_cast(runtime->getMaxWorkGroupSize(mKernel_clip[seq_idx])); + + int seq_len_piece = ROUND_UP(seq_len, tile_mn) / mQseqSplitNum; + + mGlobalWorkSizeClip[seq_idx] = {static_cast(UP_DIV(seq_len_piece, 4)), static_cast(UP_DIV(mHeadDim, 4)), static_cast(batch*mNumHead)}; + + uint32_t index = 0; + cl_int ret = CL_SUCCESS; + ret |= mKernel_clip[seq_idx]->get().setArg(index++, mGlobalWorkSizeClip[seq_idx][0]); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, mGlobalWorkSizeClip[seq_idx][1]); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, mGlobalWorkSizeClip[seq_idx][2]); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, openCLBuffer(mTempQKV.get())); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, openCLBuffer(outputs[0])); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, tile_mn); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, seq_len); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, seq_len_piece); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, mNumHead); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, mHeadDim); + ret |= mKernel_clip[seq_idx]->get().setArg(index++, seq_idx); + + mLocalWorkSizeClip[seq_idx] = localWS3DDefault(mGlobalWorkSizeClip[seq_idx], maxWorkGroupSize, runtime, "clip_transpose_qkv", mKernel_clip[seq_idx]).first; + MNN_CHECK_CL_SUCCESS(ret, "setArg clip_transpose_qkv"); + mOpenCLBackend->recordKernel3d(mKernel_clip[seq_idx], mGlobalWorkSizeClip[seq_idx], mLocalWorkSizeClip[seq_idx]); + } + } + mOpenCLBackend->endRecord(mRecording); + return NO_ERROR; +} + +ErrorCode SelfAttentionBufImpl::onExecute(Backend *backend, const std::vector &inputs, const std::vector &outputs) { +#ifdef LOG_VERBOSE + MNN_PRINT("start SelfAttentionBufExecution onExecute !\n"); +#endif + mOpenCLBackend = static_cast(backend); +#ifdef ENABLE_OPENCL_TIME_PROFILER + int batch = inputs[0]->shape()[0]; + int seqLen = inputs[0]->shape()[1]; + int headDim = inputs[0]->shape()[2]/3/mNumHead; + + std::string name; + name += "-b" + std::to_string(batch); + name += "-s" + std::to_string(seqLen); + name += "-h" + std::to_string(mNumHead); + name += "-d" + std::to_string(headDim); + + for(int seq_idx = 0; seq_idx < mQseqSplitNum; seq_idx++) { + { + cl::Event event; + run3DKernelDefault(mKernel_split[seq_idx], mGlobalWorkSizeSplit[seq_idx], mLocalWorkSizeSplit[seq_idx], + mOpenCLBackend->getOpenCLRuntime(), &event); + + mOpenCLBackend->getOpenCLRuntime()->pushEvent({"While-gemm-split" + name, event}); + } + { + cl::Event event; + run3DKernelDefault(mKernel_qk[seq_idx], mGlobalWorkSizeQk[seq_idx], mLocalWorkSizeQk[seq_idx], + mOpenCLBackend->getOpenCLRuntime(), &event); + + mOpenCLBackend->getOpenCLRuntime()->pushEvent({"While-gemm-batchgemm" + name, event}); + } + { + cl::Event event; + run3DKernelDefault(mKernel_softmax[seq_idx], mGlobalWorkSizeSoftMax[seq_idx], mLocalWorkSizeSoftMax[seq_idx], + mOpenCLBackend->getOpenCLRuntime(), &event); + + mOpenCLBackend->getOpenCLRuntime()->pushEvent({"While-gemm-softmax" + name, event}); + } + { + cl::Event event; + run3DKernelDefault(mKernel_trans[seq_idx], mGlobalWorkSizeTrans[seq_idx], mLocalWorkSizeTrans[seq_idx], mOpenCLBackend->getOpenCLRuntime(), &event); + mOpenCLBackend->getOpenCLRuntime()->pushEvent({"While-gemm-trans-1" + name, event}); + } + { + cl::Event event; + run3DKernelDefault(mKernel_qkv[seq_idx], mGlobalWorkSizeQkv[seq_idx], mLocalWorkSizeQkv[seq_idx], + mOpenCLBackend->getOpenCLRuntime(), &event); + + mOpenCLBackend->getOpenCLRuntime()->pushEvent({"While-gemm-batchgemm" + name, event}); + } + { + cl::Event event; + run3DKernelDefault(mKernel_clip[seq_idx], mGlobalWorkSizeClip[seq_idx], mLocalWorkSizeClip[seq_idx], + mOpenCLBackend->getOpenCLRuntime(), &event); + + mOpenCLBackend->getOpenCLRuntime()->pushEvent({"While-gemm-clip" + name, event}); + } + } +#else + for(int seq_idx = 0; seq_idx < mQseqSplitNum; seq_idx++) { + run3DKernelDefault(mKernel_split[seq_idx], mGlobalWorkSizeSplit[seq_idx], mLocalWorkSizeSplit[seq_idx], mOpenCLBackend->getOpenCLRuntime()); + run3DKernelDefault(mKernel_qk[seq_idx], mGlobalWorkSizeQk[seq_idx], mLocalWorkSizeQk[seq_idx], mOpenCLBackend->getOpenCLRuntime()); + run3DKernelDefault(mKernel_softmax[seq_idx], mGlobalWorkSizeSoftMax[seq_idx], mLocalWorkSizeSoftMax[seq_idx], mOpenCLBackend->getOpenCLRuntime()); + + run3DKernelDefault(mKernel_trans[seq_idx], mGlobalWorkSizeTrans[seq_idx], mLocalWorkSizeTrans[seq_idx], mOpenCLBackend->getOpenCLRuntime()); + run3DKernelDefault(mKernel_qkv[seq_idx], mGlobalWorkSizeQkv[seq_idx], mLocalWorkSizeQkv[seq_idx], mOpenCLBackend->getOpenCLRuntime()); + run3DKernelDefault(mKernel_clip[seq_idx], mGlobalWorkSizeClip[seq_idx], mLocalWorkSizeClip[seq_idx], mOpenCLBackend->getOpenCLRuntime()); + + #ifdef DUMP_INTERNAL_LOG + { + std::ofstream outFile("qk.txt"); + std::vector hostPtr_3(16*4096*4096); + mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueReadBuffer(openCLBuffer(mTempQK.get()), CL_TRUE, 0, 16*4096*4096*4, hostPtr_3.data()); + float max_ = -1000000.0; + float min_ = 10000000.0; + float total = 0.0; + for(int i=1; i temp) min_ = temp; + } + outFile.close(); + printf("qk max:%f min:%f avg:%f\n", max_, min_, hostPtr_3[0]+total); + } + #endif + } +#endif + +#ifdef LOG_VERBOSE + MNN_PRINT("end SelfAttentionBufExecution onExecute !\n"); +#endif + + return NO_ERROR; +} + +SelfAttentionBufExecution::SelfAttentionBufExecution(const MNN::Op *op, Backend* backend) : CommonExecution(backend, op) { + mImpl.reset(new SelfAttentionBufImpl(op, backend)); +} + +SelfAttentionBufExecution::SelfAttentionBufExecution(std::shared_ptr impl, const MNN::Op *op, Backend *backend) : CommonExecution(backend, op), mImpl(impl) {} + +ErrorCode SelfAttentionBufExecution::onResize(const std::vector& inputs, const std::vector& outputs) { + return mImpl->onResize(backend(), inputs, outputs); +} + +ErrorCode SelfAttentionBufExecution::onExecute(const std::vector& inputs, const std::vector& outputs) { + return mImpl->onExecute(backend(), inputs, outputs); +} + +bool SelfAttentionBufExecution::onClone(Backend* bn, const Op* op, Execution** dst) { + if (nullptr == dst) { + return true; + } + *dst = new SelfAttentionBufExecution(mImpl, op, bn); + return true; +} + +class SelfAttentionBufCreator : public OpenCLBackend::Creator { +public: + virtual Execution *onCreate(const std::vector &inputs, const std::vector &outputs, + const MNN::Op *op, Backend *backend) const override { + for (int i = 0; i < inputs.size(); ++i) { + TensorUtils::setTensorSupportPack(inputs[i], false); + } + for (int i = 0; i < outputs.size(); ++i) { + TensorUtils::setTensorSupportPack(outputs[i], false); + } + return new SelfAttentionBufExecution(op, backend); + } +}; +REGISTER_OPENCL_OP_CREATOR(SelfAttentionBufCreator, OpType_FmhaV2, BUFFER); + +} // namespace OpenCL +} // namespace MNN +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ +#endif/* MNN_OPENCL_BUFFER_CLOSED */ diff --git a/source/backend/opencl/execution/buffer/SelfAttentionBufExecution.hpp b/source/backend/opencl/execution/buffer/SelfAttentionBufExecution.hpp new file mode 100644 index 000000000..31786f666 --- /dev/null +++ b/source/backend/opencl/execution/buffer/SelfAttentionBufExecution.hpp @@ -0,0 +1,79 @@ +// +// FmhaV2Execution.hpp +// MNN +// +// Created by MNN on 2024/06/03. +// Copyright © 2018, Alibaba Group Holding Limited +// +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE + +#ifndef SelfAttentionBufExecution_hpp +#define SelfAttentionBufExecution_hpp + +#include "backend/opencl/execution/image/CommonExecution.hpp" + +namespace MNN { +namespace OpenCL { + +class SelfAttentionBufImpl { +public: + SelfAttentionBufImpl(const MNN::Op *op, Backend *backend); + + ~SelfAttentionBufImpl() = default; + ErrorCode onResize(Backend *backend, const std::vector &inputs, const std::vector &outputs); + ErrorCode onExecute(Backend *backend, const std::vector &inputs, const std::vector &outputs); + +private: + int getLocalSize(int size, int maxGroupSize); + float mScale; + int mQseqSplitNum = 1; + std::shared_ptr mTempQ, mTempK, mTempQK, mTempSoftMax, mTempV, mTempQKV; + std::shared_ptr mTempTrans; + int mNumHead = 0, mHeadDim = 0; + std::vector> mKernel_split; + std::vector> mKernel_qk; + std::vector> mKernel_softmax; + std::vector> mKernel_qkv; + std::vector> mKernel_clip; + std::vector> mKernel_trans; + std::vector> mGlobalWorkSizeSplit; + std::vector> mLocalWorkSizeSplit; + std::vector> mGlobalWorkSizeClip; + std::vector> mLocalWorkSizeClip; + std::vector> mGlobalWorkSizeQk; + std::vector> mLocalWorkSizeQk; + std::vector> mGlobalWorkSizeSoftMax; + std::vector> mLocalWorkSizeSoftMax; + std::vector> mGlobalWorkSizeQkv; + std::vector> mLocalWorkSizeQkv; + std::vector> mGlobalWorkSizeTrans; + std::vector> mLocalWorkSizeTrans; + uint32_t mMaxWorkGroupSize; + OpenCLBackend *mOpenCLBackend; + size_t mQkGlobal_size[3]; + int mSoftmaxShape[4]; + int mByte = 4; + cl_recording_qcom mRecording{NULL}; + +}; + +class SelfAttentionBufExecution : public CommonExecution { +public: + SelfAttentionBufExecution(const MNN::Op *op, Backend *backend); + SelfAttentionBufExecution(std::shared_ptr impl, const MNN::Op *op, Backend *backend); + + virtual ~SelfAttentionBufExecution() = default; + virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override; + virtual ErrorCode onExecute(const std::vector &inputs, const std::vector &outputs) override; + virtual bool onClone(Backend* bn, const Op* op, Execution** dst) override; + +private: + std::shared_ptr mImpl; +}; +} // namespace OpenCL +} // namespace MNN +#endif /* SelfAttentionBufExecution_hpp */ +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ + +#endif /* MNN_OPENCL_BUFFER_CLOSED */ diff --git a/source/backend/opencl/execution/buffer/SplitGeluBufExecution.cpp b/source/backend/opencl/execution/buffer/SplitGeluBufExecution.cpp new file mode 100644 index 000000000..171ee58a1 --- /dev/null +++ b/source/backend/opencl/execution/buffer/SplitGeluBufExecution.cpp @@ -0,0 +1,103 @@ + +// +// SplitGeluBufExecution.cpp +// MNN +// +// Created by MNN on 2024/06/26. +// Copyright © 2018, Alibaba Group Holding Limited +// +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE + +#include "backend/opencl/execution/buffer/SplitGeluBufExecution.hpp" + +namespace MNN { +namespace OpenCL { + +SplitGeluBufExecution::SplitGeluBufExecution(const MNN::Op* op, Backend* backend) : CommonExecution(backend, op) { + mOpenCLBackend = static_cast(backend); +} + +ErrorCode SplitGeluBufExecution::onEncode(const std::vector& inputs, const std::vector& outputs) { + auto runtime = static_cast(backend())->getOpenCLRuntime(); + + MNN_ASSERT(outputs.size() == 1); + auto input = inputs[0]; + auto output = outputs[0]; + MNN_ASSERT(input->dimensions() == 3); + MNN_ASSERT(output->dimensions() == 3); + if(inputs.size() > 1) { + MNN_ASSERT(inputs[1]->dimensions() == 1); + MNN_ASSERT(inputs[1]->length(0) == inputs[0]->length(2)); + } + + mUnits.clear(); + mUnits.resize(1); + std::vector outputShape = tensorShapeFormat(output); + int shape[4] = {outputShape[0], outputShape[3], outputShape[1], outputShape[2]}; + std::set buildOptions; + if(inputs.size() > 1) { + buildOptions.emplace("-DDOUBLE_INPUTS"); + } + int pack_wh = 1; + if(shape[2] % 4 == 0) { + pack_wh = 4; + buildOptions.emplace("-DWH_4"); + } + auto &unit = mUnits[0]; + std::string kernelName = "splitgelu_buf"; + unit.kernel = runtime->buildKernel("splitgelu_buf", kernelName, buildOptions); + + auto maxWorkGroupSize = static_cast(runtime->getMaxWorkGroupSize(unit.kernel)); + + mGWS = {static_cast(shape[0]), + static_cast(UP_DIV(shape[1], 4)), + static_cast(UP_DIV(shape[2],pack_wh))}; + + uint32_t idx = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel->get().setArg(idx++, mGWS[0]); + ret |= unit.kernel->get().setArg(idx++, mGWS[1]); + ret |= unit.kernel->get().setArg(idx++, mGWS[2]); + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(input)); + if(inputs.size() > 1) { + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(inputs[1])); + } + ret |= unit.kernel->get().setArg(idx++, openCLBuffer(output)); + ret |= unit.kernel->get().setArg(idx++, sizeof(shape), shape); + + MNN_CHECK_CL_SUCCESS(ret, "setArg SplitGeluBufExecution"); + + mLWS = localWS3DDefault(mGWS, maxWorkGroupSize, runtime, "splitgelu_buf", unit.kernel).first; + + unit.globalWorkSize = {mGWS[0], mGWS[1], mGWS[2]}; + unit.localWorkSize = {mLWS[0], mLWS[1], mLWS[2]}; + + mOpenCLBackend->recordKernel3d(unit.kernel, mGWS, mLWS); + mOpenCLBackend->endRecord(mRecording); + return NO_ERROR; + +} + + +class SplitGeluBufCreator : public OpenCLBackend::Creator { +public: + virtual ~SplitGeluBufCreator() = default; + virtual Execution *onCreate(const std::vector &inputs, const std::vector &outputs, + const MNN::Op *op, Backend *backend) const override { + for (int i = 0; i < inputs.size(); ++i) { + TensorUtils::setTensorSupportPack(inputs[i], false); + } + for (int i = 0; i < outputs.size(); ++i) { + TensorUtils::setTensorSupportPack(outputs[i], false); + } + + return new SplitGeluBufExecution(op, backend); + } +}; + +REGISTER_OPENCL_OP_CREATOR(SplitGeluBufCreator, OpType_SplitGeLU, BUFFER); +} // namespace OpenCL +} // namespace MNN +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ +#endif/* MNN_OPENCL_BUFFER_CLOSED */ diff --git a/source/backend/opencl/execution/buffer/SplitGeluBufExecution.hpp b/source/backend/opencl/execution/buffer/SplitGeluBufExecution.hpp new file mode 100644 index 000000000..9ecd65b8b --- /dev/null +++ b/source/backend/opencl/execution/buffer/SplitGeluBufExecution.hpp @@ -0,0 +1,39 @@ +// +// SplitGeluBufExecution.hpp +// MNN +// +// Created by MNN on 2024/06/26. +// Copyright © 2018, Alibaba Group Holding Limited +// +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_TRANSFORMER_FUSE + +#ifndef SplitGeluBufExecution_hpp +#define SplitGeluBufExecution_hpp + +#include "backend/opencl/execution/image/CommonExecution.hpp" + +namespace MNN { + +namespace OpenCL { +class SplitGeluBufExecution : public CommonExecution { +public: + SplitGeluBufExecution(const MNN::Op* op, Backend *backend); + virtual ~SplitGeluBufExecution() = default; + + virtual ErrorCode onEncode(const std::vector &inputs, const std::vector &outputs) override; + +private: + OpenCLBackend *mOpenCLBackend; + float mFDiv{}; + float mFAdd{}; + float mFMul{}; + std::vector mLWS{0, 0, 0, 0}; + std::vector mGWS{0, 0, 0, 0}; +}; + +} // namespace OPENCL +} // namespace MNN +#endif /* SplitGeluBufExecution_hpp */ +#endif/* MNN_SUPPORT_TRANSFORMER_FUSE */ +#endif diff --git a/source/backend/opencl/execution/cl/argmax_buf.cl b/source/backend/opencl/execution/cl/argmax_buf.cl index 48b2b3acc..5240eea4e 100644 --- a/source/backend/opencl/execution/cl/argmax_buf.cl +++ b/source/backend/opencl/execution/cl/argmax_buf.cl @@ -14,13 +14,13 @@ __private const int global_size_dim0, __private const int global_size_dim1, __pr if(A.x < B.x){ A.x = B.x; C.x = D; } \ if(A.y < B.y){ A.y = B.y; C.y = D; } \ if(A.z < B.z){ A.z = B.z; C.z = D; } \ - if(A.w < B.w){ A.w = B.w; C.w = D; } \ + if(A.w < B.w){ A.w = B.w; C.w = D; } #define ARGMIN_SELECT(A, B, C, D) \ if(A.x > B.x){ A.x = B.x; C.x = D; } \ if(A.y > B.y){ A.y = B.y; C.y = D; } \ if(A.z > B.z){ A.z = B.z; C.z = D; } \ - if(A.w > B.w){ A.w = B.w; C.w = D; } \ + if(A.w > B.w){ A.w = B.w; C.w = D; } __kernel void argmax_width_buf(GLOBAL_SIZE_3_DIMS __global const FLOAT* input, diff --git a/source/backend/opencl/execution/cl/attention_buf.cl b/source/backend/opencl/execution/cl/attention_buf.cl index a1f6f9113..c17be5a4f 100644 --- a/source/backend/opencl/execution/cl/attention_buf.cl +++ b/source/backend/opencl/execution/cl/attention_buf.cl @@ -15,7 +15,7 @@ __kernel void matmul_qk_div_mask(GLOBAL_SIZE_3_DIMS __global const FLOAT *input0, // query [1 query_seq_len/4 head_num head_dim 4] __global const FLOAT *input1, // key [1 key_seq_len/4 head_num head_dim 4] __global FLOAT *output, // prefill [1 head_num query_seq_len/4 key_seq_len 4] decode[1 head_num key_seq_len/4 4] - __global FLOAT *past_key, // [1 key_seq_len/4 head_num head_dim 4] + __global FLOAT *past_key, // [1 head_num max_length/4 head_dim 4] #ifdef ADD_MASK __global const FLOAT* mask, #else @@ -25,6 +25,7 @@ __kernel void matmul_qk_div_mask(GLOBAL_SIZE_3_DIMS __private const int query_seq_len, __private const int key_seq_len, __private const int head_num, + __private const int kv_head_num, __private const int head_dim) { const int x = get_global_id(0); // query_seq_len / 4 for prefill 1 for decode @@ -32,85 +33,86 @@ __kernel void matmul_qk_div_mask(GLOBAL_SIZE_3_DIMS const int z = get_global_id(2); // key_seq_len / 4 DEAL_NON_UNIFORM_DIM3(x, y, z); + int yin = y / NUMHEAD_GROUP_SIZE; const int offset = head_num * head_dim * 4; const int offset_head = y * head_dim * 4; __global const FLOAT *A_offset = input0 + x * offset + offset_head; - __global FLOAT *Pastkey_offset = past_key + z * offset + offset_head; + __global FLOAT *Pastkey_offset = past_key + (z * kv_head_num + yin) * head_dim * 4; const int z4 = z << 2; - COMPUTE_FLOAT4 Vscale = (COMPUTE_FLOAT4)scale; + float4 Vscale = (float4)scale; #ifdef OPENCL_PREFILL_ATTENTION - __global const FLOAT *B_offset = input1 + z * offset + offset_head; + __global const FLOAT *B_offset = input1 + (z * kv_head_num + yin) * head_dim * 4; const int x4 = x << 2; const int query_seq_len4 = (query_seq_len + 3) / 4; const int output_offset = y * query_seq_len4 * key_seq_len * 4; - COMPUTE_FLOAT4 out0 = 0; - COMPUTE_FLOAT4 out1 = 0; - COMPUTE_FLOAT4 out2 = 0; - COMPUTE_FLOAT4 out3 = 0; + float4 out0 = 0; + float4 out1 = 0; + float4 out2 = 0; + float4 out3 = 0; const int head_dim4 = (head_dim + 3) / 4; #ifdef HEADDIM_LEAVE for(int i = 0; i < head_dim4 - 1; ++i){ - COMPUTE_FLOAT16 A = CONVERT_COMPUTE_FLOAT16(vload16(i, A_offset)); - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(i, B_offset)); + float16 A = convert_float16(vload16(i, A_offset)); + float16 B = convert_float16(vload16(i, B_offset)); - out0 = mad(A.s0123, (COMPUTE_FLOAT4)B.s0, out0); - out1 = mad(A.s0123, (COMPUTE_FLOAT4)B.s1, out1); - out2 = mad(A.s0123, (COMPUTE_FLOAT4)B.s2, out2); - out3 = mad(A.s0123, (COMPUTE_FLOAT4)B.s3, out3); + out0 = mad(A.s0123, (float4)B.s0, out0); + out1 = mad(A.s0123, (float4)B.s1, out1); + out2 = mad(A.s0123, (float4)B.s2, out2); + out3 = mad(A.s0123, (float4)B.s3, out3); - out0 = mad(A.s4567, (COMPUTE_FLOAT4)B.s4, out0); - out1 = mad(A.s4567, (COMPUTE_FLOAT4)B.s5, out1); - out2 = mad(A.s4567, (COMPUTE_FLOAT4)B.s6, out2); - out3 = mad(A.s4567, (COMPUTE_FLOAT4)B.s7, out3); + out0 = mad(A.s4567, (float4)B.s4, out0); + out1 = mad(A.s4567, (float4)B.s5, out1); + out2 = mad(A.s4567, (float4)B.s6, out2); + out3 = mad(A.s4567, (float4)B.s7, out3); - out0 = mad(A.s89ab, (COMPUTE_FLOAT4)B.s8, out0); - out1 = mad(A.s89ab, (COMPUTE_FLOAT4)B.s9, out1); - out2 = mad(A.s89ab, (COMPUTE_FLOAT4)B.sa, out2); - out3 = mad(A.s89ab, (COMPUTE_FLOAT4)B.sb, out3); + out0 = mad(A.s89ab, (float4)B.s8, out0); + out1 = mad(A.s89ab, (float4)B.s9, out1); + out2 = mad(A.s89ab, (float4)B.sa, out2); + out3 = mad(A.s89ab, (float4)B.sb, out3); - out0 = mad(A.scdef, (COMPUTE_FLOAT4)B.sc, out0); - out1 = mad(A.scdef, (COMPUTE_FLOAT4)B.sd, out1); - out2 = mad(A.scdef, (COMPUTE_FLOAT4)B.se, out2); - out3 = mad(A.scdef, (COMPUTE_FLOAT4)B.sf, out3); + out0 = mad(A.scdef, (float4)B.sc, out0); + out1 = mad(A.scdef, (float4)B.sd, out1); + out2 = mad(A.scdef, (float4)B.se, out2); + out3 = mad(A.scdef, (float4)B.sf, out3); vstore16(CONVERT_FLOAT16(B), i, Pastkey_offset); } for(int i = (head_dim4 - 1) * 4; i < head_dim; ++i){ - COMPUTE_FLOAT4 A = CONVERT_COMPUTE_FLOAT4(vload4(i, A_offset)); - COMPUTE_FLOAT4 B = CONVERT_COMPUTE_FLOAT4(vload4(i, B_offset)); + float4 A = convert_float4(vload4(i, A_offset)); + float4 B = convert_float4(vload4(i, B_offset)); - out0 = mad(A, (COMPUTE_FLOAT4)B.s0, out0); - out1 = mad(A, (COMPUTE_FLOAT4)B.s1, out1); - out2 = mad(A, (COMPUTE_FLOAT4)B.s2, out2); - out3 = mad(A, (COMPUTE_FLOAT4)B.s3, out3); + out0 = mad(A, (float4)B.s0, out0); + out1 = mad(A, (float4)B.s1, out1); + out2 = mad(A, (float4)B.s2, out2); + out3 = mad(A, (float4)B.s3, out3); vstore4(CONVERT_FLOAT4(B), i, Pastkey_offset); } #else for(int i = 0; i < head_dim4; ++i){ - COMPUTE_FLOAT16 A = CONVERT_COMPUTE_FLOAT16(vload16(i, A_offset)); - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(i, B_offset)); + float16 A = convert_float16(vload16(i, A_offset)); + float16 B = convert_float16(vload16(i, B_offset)); - out0 = mad(A.s0123, (COMPUTE_FLOAT4)B.s0, out0); - out1 = mad(A.s0123, (COMPUTE_FLOAT4)B.s1, out1); - out2 = mad(A.s0123, (COMPUTE_FLOAT4)B.s2, out2); - out3 = mad(A.s0123, (COMPUTE_FLOAT4)B.s3, out3); + out0 = mad(A.s0123, (float4)B.s0, out0); + out1 = mad(A.s0123, (float4)B.s1, out1); + out2 = mad(A.s0123, (float4)B.s2, out2); + out3 = mad(A.s0123, (float4)B.s3, out3); - out0 = mad(A.s4567, (COMPUTE_FLOAT4)B.s4, out0); - out1 = mad(A.s4567, (COMPUTE_FLOAT4)B.s5, out1); - out2 = mad(A.s4567, (COMPUTE_FLOAT4)B.s6, out2); - out3 = mad(A.s4567, (COMPUTE_FLOAT4)B.s7, out3); + out0 = mad(A.s4567, (float4)B.s4, out0); + out1 = mad(A.s4567, (float4)B.s5, out1); + out2 = mad(A.s4567, (float4)B.s6, out2); + out3 = mad(A.s4567, (float4)B.s7, out3); - out0 = mad(A.s89ab, (COMPUTE_FLOAT4)B.s8, out0); - out1 = mad(A.s89ab, (COMPUTE_FLOAT4)B.s9, out1); - out2 = mad(A.s89ab, (COMPUTE_FLOAT4)B.sa, out2); - out3 = mad(A.s89ab, (COMPUTE_FLOAT4)B.sb, out3); + out0 = mad(A.s89ab, (float4)B.s8, out0); + out1 = mad(A.s89ab, (float4)B.s9, out1); + out2 = mad(A.s89ab, (float4)B.sa, out2); + out3 = mad(A.s89ab, (float4)B.sb, out3); - out0 = mad(A.scdef, (COMPUTE_FLOAT4)B.sc, out0); - out1 = mad(A.scdef, (COMPUTE_FLOAT4)B.sd, out1); - out2 = mad(A.scdef, (COMPUTE_FLOAT4)B.se, out2); - out3 = mad(A.scdef, (COMPUTE_FLOAT4)B.sf, out3); + out0 = mad(A.scdef, (float4)B.sc, out0); + out1 = mad(A.scdef, (float4)B.sd, out1); + out2 = mad(A.scdef, (float4)B.se, out2); + out3 = mad(A.scdef, (float4)B.sf, out3); vstore16(CONVERT_FLOAT16(B), i, Pastkey_offset); } @@ -121,46 +123,22 @@ __kernel void matmul_qk_div_mask(GLOBAL_SIZE_3_DIMS out2 *= Vscale; out3 *= Vscale; + float4 mask0, mask1, mask2, mask3; + mask = mask + (x4 * key_seq_len + z4) * 4; + mask0.s0 = mask[0]; mask1.s0 = mask[4]; mask2.s0 = mask[8]; mask3.s0 = mask[12]; mask += key_seq_len * 4; + mask0.s1 = mask[0]; mask1.s1 = mask[4]; mask2.s1 = mask[8]; mask3.s1 = mask[12]; mask += key_seq_len * 4; + mask0.s2 = mask[0]; mask1.s2 = mask[4]; mask2.s2 = mask[8]; mask3.s2 = mask[12]; mask += key_seq_len * 4; + mask0.s3 = mask[0]; mask1.s3 = mask[4]; mask2.s3 = mask[8]; mask3.s3 = mask[12]; #ifdef ADD_MASK - out0.s0 += mask[((x4 + 0) * key_seq_len + (z4 + 0)) * 4]; - out1.s0 += mask[((x4 + 0) * key_seq_len + (z4 + 1)) * 4]; - out2.s0 += mask[((x4 + 0) * key_seq_len + (z4 + 2)) * 4]; - out3.s0 += mask[((x4 + 0) * key_seq_len + (z4 + 3)) * 4]; - - out0.s1 += mask[((x4 + 1) * key_seq_len + (z4 + 0)) * 4]; - out1.s1 += mask[((x4 + 1) * key_seq_len + (z4 + 1)) * 4]; - out2.s1 += mask[((x4 + 1) * key_seq_len + (z4 + 2)) * 4]; - out3.s1 += mask[((x4 + 1) * key_seq_len + (z4 + 3)) * 4]; - - out0.s2 += mask[((x4 + 2) * key_seq_len + (z4 + 0)) * 4]; - out1.s2 += mask[((x4 + 2) * key_seq_len + (z4 + 1)) * 4]; - out2.s2 += mask[((x4 + 2) * key_seq_len + (z4 + 2)) * 4]; - out3.s2 += mask[((x4 + 2) * key_seq_len + (z4 + 3)) * 4]; - - out0.s3 += mask[((x4 + 3) * key_seq_len + (z4 + 0)) * 4]; - out1.s3 += mask[((x4 + 3) * key_seq_len + (z4 + 1)) * 4]; - out2.s3 += mask[((x4 + 3) * key_seq_len + (z4 + 2)) * 4]; - out3.s3 += mask[((x4 + 3) * key_seq_len + (z4 + 3)) * 4]; + out0 += mask0; + out1 += mask1; + out2 += mask2; + out3 += mask3; #else - out0.s0 = mask[((x4 + 0) * key_seq_len + (z4 + 0)) * 4] == 0 ? -FLT_MAX : out0.s0; - out1.s0 = mask[((x4 + 0) * key_seq_len + (z4 + 1)) * 4] == 0 ? -FLT_MAX : out1.s0; - out2.s0 = mask[((x4 + 0) * key_seq_len + (z4 + 2)) * 4] == 0 ? -FLT_MAX : out2.s0; - out3.s0 = mask[((x4 + 0) * key_seq_len + (z4 + 3)) * 4] == 0 ? -FLT_MAX : out3.s0; - - out0.s1 = mask[((x4 + 1) * key_seq_len + (z4 + 0)) * 4] == 0 ? -FLT_MAX : out0.s1; - out1.s1 = mask[((x4 + 1) * key_seq_len + (z4 + 1)) * 4] == 0 ? -FLT_MAX : out1.s1; - out2.s1 = mask[((x4 + 1) * key_seq_len + (z4 + 2)) * 4] == 0 ? -FLT_MAX : out2.s1; - out3.s1 = mask[((x4 + 1) * key_seq_len + (z4 + 3)) * 4] == 0 ? -FLT_MAX : out3.s1; - - out0.s2 = mask[((x4 + 2) * key_seq_len + (z4 + 0)) * 4] == 0 ? -FLT_MAX : out0.s2; - out1.s2 = mask[((x4 + 2) * key_seq_len + (z4 + 1)) * 4] == 0 ? -FLT_MAX : out1.s2; - out2.s2 = mask[((x4 + 2) * key_seq_len + (z4 + 2)) * 4] == 0 ? -FLT_MAX : out2.s2; - out3.s2 = mask[((x4 + 2) * key_seq_len + (z4 + 3)) * 4] == 0 ? -FLT_MAX : out3.s2; - - out0.s3 = mask[((x4 + 3) * key_seq_len + (z4 + 0)) * 4] == 0 ? -FLT_MAX : out0.s3; - out1.s3 = mask[((x4 + 3) * key_seq_len + (z4 + 1)) * 4] == 0 ? -FLT_MAX : out1.s3; - out2.s3 = mask[((x4 + 3) * key_seq_len + (z4 + 2)) * 4] == 0 ? -FLT_MAX : out2.s3; - out3.s3 = mask[((x4 + 3) * key_seq_len + (z4 + 3)) * 4] == 0 ? -FLT_MAX : out3.s3; + out0 = (mask0 == (float4)0) ? (float4)(-FLT_MAX) : out0; + out1 = (mask1 == (float4)0) ? (float4)(-FLT_MAX) : out1; + out2 = (mask2 == (float4)0) ? (float4)(-FLT_MAX) : out2; + out3 = (mask3 == (float4)0) ? (float4)(-FLT_MAX) : out3; #endif vstore4(CONVERT_FLOAT4(out0), 0, output + output_offset + x * key_seq_len * 4 + z4 * 4); @@ -171,49 +149,49 @@ __kernel void matmul_qk_div_mask(GLOBAL_SIZE_3_DIMS if(z4 + 3 >= key_seq_len) return; vstore4(CONVERT_FLOAT4(out3), 0, output + output_offset + x * key_seq_len * 4 + (z4 + 3) * 4); #else - __global const FLOAT *B_offset = input1 + offset_head; + __global const FLOAT *B_offset = input1 + yin * head_dim * 4; const int key_seq_len4 = (key_seq_len + 3) / 4; - COMPUTE_FLOAT4 out = 0; + float4 out = 0; const int head_dim4 = (head_dim + 3) / 4; #ifdef HEADDIM_LEAVE for(int i = 0; i < head_dim4 - 1; ++i){ - COMPUTE_FLOAT16 A = CONVERT_COMPUTE_FLOAT16(vload16(i, A_offset)); - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(i, Pastkey_offset)); + float16 A = convert_float16(vload16(i, A_offset)); + float16 B = convert_float16(vload16(i, Pastkey_offset)); - out = mad((COMPUTE_FLOAT4)A.s0, B.s0123, out); - out = mad((COMPUTE_FLOAT4)A.s4, B.s4567, out); - out = mad((COMPUTE_FLOAT4)A.s8, B.s89ab, out); - out = mad((COMPUTE_FLOAT4)A.sc, B.scdef, out); + out = mad((float4)A.s0, B.s0123, out); + out = mad((float4)A.s4, B.s4567, out); + out = mad((float4)A.s8, B.s89ab, out); + out = mad((float4)A.sc, B.scdef, out); } for(int i = (head_dim4 - 1) * 4; i < head_dim; ++i){ - COMPUTE_FLOAT4 A = CONVERT_COMPUTE_FLOAT4(vload4(i, A_offset)); - COMPUTE_FLOAT4 B = CONVERT_COMPUTE_FLOAT4(vload4(i, Pastkey_offset)); + float4 A = convert_float4(vload4(i, A_offset)); + float4 B = convert_float4(vload4(i, Pastkey_offset)); - out = mad((COMPUTE_FLOAT4)A.s0, B, out); + out = mad((float4)A.s0, B, out); } #else for(int i = 0; i < head_dim4; ++i){ - COMPUTE_FLOAT16 A = CONVERT_COMPUTE_FLOAT16(vload16(i, A_offset)); - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(i, Pastkey_offset)); + float16 A = convert_float16(vload16(i, A_offset)); + float16 B = convert_float16(vload16(i, Pastkey_offset)); - out = mad((COMPUTE_FLOAT4)A.s0, B.s0123, out); - out = mad((COMPUTE_FLOAT4)A.s4, B.s4567, out); - out = mad((COMPUTE_FLOAT4)A.s8, B.s89ab, out); - out = mad((COMPUTE_FLOAT4)A.sc, B.scdef, out); + out = mad((float4)A.s0, B.s0123, out); + out = mad((float4)A.s4, B.s4567, out); + out = mad((float4)A.s8, B.s89ab, out); + out = mad((float4)A.sc, B.scdef, out); } #endif if(z == key_seq_len4 - 1){ int remain = key_seq_len - z * 4 - 1; Pastkey_offset += remain; - COMPUTE_FLOAT tmp = 0; + float tmp = 0; for(int i = 0; i < head_dim; ++i){ - COMPUTE_FLOAT A = A_offset[i*4]; - COMPUTE_FLOAT B = B_offset[i*4]; + float A = A_offset[i*4]; + float B = B_offset[i*4]; Pastkey_offset[i * 4] = B; tmp += A * B; } - COMPUTE_FLOAT *out_ptr = (COMPUTE_FLOAT*)&out; + float *out_ptr = (float*)&out; out_ptr[remain] = tmp; } out *= Vscale; @@ -229,6 +207,7 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS __private const int qk_seq_len, __private const int value_seq_len, __private const int head_num, + __private const int kv_head_num, __private const int head_dim) { const int x = get_global_id(0); // prefill qk_seq_len / 4 decode 1 @@ -237,14 +216,16 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS const int z4 = z << 2; DEAL_NON_UNIFORM_DIM3(x, y, z); + const int yin = y / NUMHEAD_GROUP_SIZE; #ifdef OPENCL_PREFILL_ATTENTION const int offset = head_num * head_dim * 4; + const int stride = kv_head_num * head_dim * 4; const int offset_head = y * head_dim * 4 + z4 * 4; const int value_seq_len4 = (value_seq_len + 3) / 4; const int qk_seq_len4 = (qk_seq_len + 3) / 4; __global const FLOAT *A_offset = input0 + (y * qk_seq_len4 + x) * value_seq_len * 4; - __global const FLOAT *B_offset = input1 + offset_head; - __global FLOAT *Pastvalue_offset = past_value + offset_head; + __global const FLOAT *B_offset = input1 + yin * head_dim * 4 + z4 * 4; + __global FLOAT *Pastvalue_offset = past_value + yin * head_dim * 4 + z4 * 4; COMPUTE_FLOAT4 out0 = 0; COMPUTE_FLOAT4 out1 = 0; COMPUTE_FLOAT4 out2 = 0; @@ -256,7 +237,7 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS COMPUTE_FLOAT4 A1 = CONVERT_COMPUTE_FLOAT4(vload4(index + 1, A_offset)); COMPUTE_FLOAT4 A2 = CONVERT_COMPUTE_FLOAT4(vload4(index + 2, A_offset)); COMPUTE_FLOAT4 A3 = CONVERT_COMPUTE_FLOAT4(vload4(index + 3, A_offset)); - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, B_offset + i * offset)); + COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, B_offset + i * stride)); out0 = mad(A0, (COMPUTE_FLOAT4)B.s0, out0); out0 = mad(A1, (COMPUTE_FLOAT4)B.s1, out0); @@ -278,11 +259,11 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS out3 = mad(A2, (COMPUTE_FLOAT4)B.se, out3); out3 = mad(A3, (COMPUTE_FLOAT4)B.sf, out3); - vstore16(CONVERT_FLOAT16(B), 0, Pastvalue_offset + i * offset); + vstore16(CONVERT_FLOAT16(B), 0, Pastvalue_offset + i * stride); } #ifdef HEADDIM_LEAVE - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, B_offset + (value_seq_len4 - 1) * offset)); + COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, B_offset + (value_seq_len4 - 1) * stride)); COMPUTE_FLOAT *B_ptr = (COMPUTE_FLOAT*)&B; for(int i = (value_seq_len4 - 1) * 4, j = 0; i < value_seq_len; ++i, ++j){ COMPUTE_FLOAT4 A0 = CONVERT_COMPUTE_FLOAT4(vload4(i, A_offset)); @@ -292,19 +273,19 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS out3 = mad(A0, (COMPUTE_FLOAT4)B_ptr[j + 12], out3); } vstore4(CONVERT_FLOAT4(out0), 0, output + x * offset + (y * head_dim + z4) * 4); - vstore4(CONVERT_FLOAT4(B.s0123), 0, Pastvalue_offset + (value_seq_len4 - 1) * offset); + vstore4(CONVERT_FLOAT4(B.s0123), 0, Pastvalue_offset + (value_seq_len4 - 1) * stride); if(z4 + 1 >= head_dim) return; vstore4(CONVERT_FLOAT4(out1), 0, output + x * offset + (y * head_dim + z4 + 1) * 4); - vstore4(CONVERT_FLOAT4(B.s4567), 1, Pastvalue_offset + (value_seq_len4 - 1) * offset); + vstore4(CONVERT_FLOAT4(B.s4567), 1, Pastvalue_offset + (value_seq_len4 - 1) * stride); if(z4 + 2 >= head_dim) return; vstore4(CONVERT_FLOAT4(out2), 0, output + x * offset + (y * head_dim + z4 + 2) * 4); - vstore4(CONVERT_FLOAT4(B.s89ab), 2, Pastvalue_offset + (value_seq_len4 - 1) * offset); + vstore4(CONVERT_FLOAT4(B.s89ab), 2, Pastvalue_offset + (value_seq_len4 - 1) * stride); if(z4 + 3 >= head_dim) return; vstore4(CONVERT_FLOAT4(out3), 0, output + x * offset + (y * head_dim + z4 + 3) * 4); - vstore4(CONVERT_FLOAT4(B.scdef), 3, Pastvalue_offset + (value_seq_len4 - 1) * offset); + vstore4(CONVERT_FLOAT4(B.scdef), 3, Pastvalue_offset + (value_seq_len4 - 1) * stride); #else - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, B_offset + (value_seq_len4 - 1) * offset)); - vstore16(CONVERT_FLOAT16(B), 0, Pastvalue_offset + (value_seq_len4 - 1) * offset); + COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, B_offset + (value_seq_len4 - 1) * stride)); + vstore16(CONVERT_FLOAT16(B), 0, Pastvalue_offset + (value_seq_len4 - 1) * stride); COMPUTE_FLOAT *B_ptr = (COMPUTE_FLOAT*)&B; for(int i = (value_seq_len4 - 1) * 4, j = 0; i < value_seq_len; ++i, ++j){ COMPUTE_FLOAT4 A0 = CONVERT_COMPUTE_FLOAT4(vload4(i, A_offset)); @@ -318,17 +299,18 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS #else const int value_seq_len4 = (value_seq_len + 3) / 4; + const int stride = kv_head_num * head_dim * 4; const int offset = head_num * head_dim * 4; const int offset_head = y * head_dim * 4 + z4 * 4; const int loop = (value_seq_len + 2) / 4; __global const FLOAT *A_offset = input0 + y * value_seq_len4 * 4; - __global const FLOAT *B_offset = input1 + offset_head; - __global FLOAT *Pastvalue_offset = past_value + offset_head; + __global const FLOAT *B_offset = input1 + yin * head_dim * 4 + z4 * 4; + __global FLOAT *Pastvalue_offset = past_value + yin * head_dim * 4 + z4 * 4; COMPUTE_FLOAT4 out = 0; for(int i = 0; i < loop - 1; i++){ COMPUTE_FLOAT4 A = CONVERT_COMPUTE_FLOAT4(vload4(i, A_offset)); - COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, Pastvalue_offset + i * offset)); + COMPUTE_FLOAT16 B = CONVERT_COMPUTE_FLOAT16(vload16(0, Pastvalue_offset + i * stride)); out.s0 += dot(A, B.s0123); out.s1 += dot(A, B.s4567); @@ -336,7 +318,7 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS out.s3 += dot(A, B.scdef); } int start = (loop - 1) < 0 ? 0 : (loop - 1); - COMPUTE_FLOAT16 B_Vec = CONVERT_COMPUTE_FLOAT16(vload16(0, Pastvalue_offset + start * offset)); + COMPUTE_FLOAT16 B_Vec = CONVERT_COMPUTE_FLOAT16(vload16(0, Pastvalue_offset + start * stride)); COMPUTE_FLOAT *B_ptr = (COMPUTE_FLOAT *)&B_Vec; for(int i = start * 4; i < value_seq_len - 1; ++i){ COMPUTE_FLOAT A = A_offset[i]; @@ -356,7 +338,7 @@ __kernel void matmul_qkv(GLOBAL_SIZE_3_DIMS out.s1 += A * B1; out.s2 += A * B2; out.s3 += A * B3; - int index = ((value_seq_len - 1) >> 2) * offset + ((value_seq_len - 1) % 4); + int index = ((value_seq_len - 1) >> 2) * stride + ((value_seq_len - 1) % 4); #ifdef HEADDIM_LEAVE Pastvalue_offset[index] = B0; diff --git a/source/backend/opencl/execution/cl/buffer_convert_buf.cl b/source/backend/opencl/execution/cl/buffer_convert_buf.cl index 0177d3d41..1563c65ea 100644 --- a/source/backend/opencl/execution/cl/buffer_convert_buf.cl +++ b/source/backend/opencl/execution/cl/buffer_convert_buf.cl @@ -290,127 +290,6 @@ __kernel void conv2d_filter_buffer_to_nc4hw4_buffer(GLOBAL_SIZE_2_DIMS vstore4(output_values, 0, output+out_offset); } -#ifdef USE_LOW_BIT_WEIGHT_INT8 -// convert kernel : from int8 buffer(oihw) to int8 image(oc/4 h w , ic oc4) -__kernel void conv2d_filter_buffer_to_nc4hw4_buffer_int8(GLOBAL_SIZE_2_DIMS - __global const char *input_ptr, - __private const int output_channel, - __private const int2 kernel_shape, - __private const int ic_h_w_size, - __private const int height_width_size, - __global char *output) { - int image_width_idx = get_global_id(0); // ic - int image_height_idx = get_global_id(1); // oc/4 h w - - DEAL_NON_UNIFORM_DIM2(image_width_idx, image_height_idx); - - const int input_channel_4_idx = image_width_idx; - const int output_channel_4_idx = (image_height_idx / height_width_size) * 4; - const int height_width_idx = image_height_idx % height_width_size; - const int buffer_height_idx = height_width_idx / kernel_shape.y; - const int buffer_width_idx = height_width_idx % kernel_shape.y; - - const int buffer_offset = output_channel_4_idx * ic_h_w_size + input_channel_4_idx * height_width_size + - buffer_height_idx * kernel_shape.y + buffer_width_idx; - - char4 output_values = 0; - if (output_channel_4_idx < output_channel) { - const int remain_channel = output_channel - output_channel_4_idx; - if (remain_channel >= 4) { - int offset = buffer_offset; - output_values.x = (char)(*(input_ptr + offset)); - offset = mad24(1, ic_h_w_size, offset); - output_values.y = (char)(*(input_ptr + offset)); - offset += ic_h_w_size; - output_values.z = (char)(*(input_ptr + offset)); - offset += ic_h_w_size; - output_values.w = (char)(*(input_ptr + offset)); - } else if (remain_channel == 3) { - int offset = buffer_offset; - output_values.x = (char)(*(input_ptr + offset)); - offset = mad24(1, ic_h_w_size, offset); - output_values.y = (char)(*(input_ptr + offset)); - offset += ic_h_w_size; - output_values.z = (char)(*(input_ptr + offset)); - - } else if (remain_channel == 2) { - int offset = buffer_offset; - output_values.x = (char)(*(input_ptr + offset)); - offset = mad24(1, ic_h_w_size, offset); - output_values.y = (char)(*(input_ptr + offset)); - } else if (remain_channel == 1) { - int offset = buffer_offset; - output_values.x = (char)(*(input_ptr + offset)); - } - } - const int out_offset = (image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*4; - vstore4(output_values, 0, output+out_offset); -} -#endif - -#ifdef USE_LOW_BIT_WEIGHT_INT4 -// convert kernel : from int8 buffer(oihw) to int4 image(oc/4 h w , ic oc4) -__kernel void conv2d_filter_buffer_to_nc4hw4_buffer_int4(GLOBAL_SIZE_2_DIMS - __global const char *input_ptr, - __private const int output_channel, - __private const int2 kernel_shape, - __private const int ic_h_w_size, - __private const int height_width_size, - __global uchar *output) { - int image_width_idx = get_global_id(0); // ic - int image_height_idx = get_global_id(1); // oc/4 h w - - DEAL_NON_UNIFORM_DIM2(image_width_idx, image_height_idx); - - const int input_channel_4_idx = image_width_idx; - const int output_channel_4_idx = (image_height_idx / height_width_size) * 4; - const int height_width_idx = image_height_idx % height_width_size; - const int buffer_height_idx = height_width_idx / kernel_shape.y; - const int buffer_width_idx = height_width_idx % kernel_shape.y; - - const int buffer_offset = output_channel_4_idx * ic_h_w_size + input_channel_4_idx * height_width_size + - buffer_height_idx * kernel_shape.y + buffer_width_idx; - - char4 output_values_int8 = 0; - if (output_channel_4_idx < output_channel) { - const int remain_channel = output_channel - output_channel_4_idx; - if (remain_channel >= 4) { - int offset = buffer_offset; - output_values_int8.x = (char)(*(input_ptr + offset)); - offset = mad24(1, ic_h_w_size, offset); - output_values_int8.y = (char)(*(input_ptr + offset)); - offset += ic_h_w_size; - output_values_int8.z = (char)(*(input_ptr + offset)); - offset += ic_h_w_size; - output_values_int8.w = (char)(*(input_ptr + offset)); - } else if (remain_channel == 3) { - int offset = buffer_offset; - output_values_int8.x = (char)(*(input_ptr + offset)); - offset = mad24(1, ic_h_w_size, offset); - output_values_int8.y = (char)(*(input_ptr + offset)); - offset += ic_h_w_size; - output_values_int8.z = (char)(*(input_ptr + offset)); - - } else if (remain_channel == 2) { - int offset = buffer_offset; - output_values_int8.x = (char)(*(input_ptr + offset)); - offset = mad24(1, ic_h_w_size, offset); - output_values_int8.y = (char)(*(input_ptr + offset)); - } else if (remain_channel == 1) { - int offset = buffer_offset; - output_values_int8.x = (char)(*(input_ptr + offset)); - } - } - - uchar2 output_values_int4 = (uchar2)(0, 0); - output_values_int4.s0 = (output_values_int8.x + 8) * 16 + (output_values_int8.y + 8); - output_values_int4.s1 = (output_values_int8.z + 8) * 16 + (output_values_int8.w + 8); - - const int out_offset = (image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*2; - vstore2(output_values_int4, 0, output+out_offset); -} -#endif - // convert kernel : from buffer(oihw) to image(oc/4 h w , ic oc4) __kernel void conv2d_filter_buffer_to_nc4hw4_buffer_floatin(GLOBAL_SIZE_2_DIMS __global const float *input_ptr, diff --git a/source/backend/opencl/execution/cl/buffer_convert_quant.cl b/source/backend/opencl/execution/cl/buffer_convert_quant.cl new file mode 100644 index 000000000..1215cc71b --- /dev/null +++ b/source/backend/opencl/execution/cl/buffer_convert_quant.cl @@ -0,0 +1,242 @@ +#ifdef MNN_SUPPORT_FP16 +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +#endif + +__constant sampler_t SAMPLER = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; +#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0, __private const int global_size_dim1, +#define DEAL_NON_UNIFORM_DIM2(input1, input2) \ + if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { \ + return; \ + } + +#ifdef USE_LOW_BIT_WEIGHT_INT8 +// convert kernel : from int8 buffer(oihw) to int8 image(oc/4 h w , ic oc4) +__kernel void conv2d_filter_buffer_to_nc4hw4_buffer_int8(GLOBAL_SIZE_2_DIMS + __global const char *input_ptr, + __private const int output_channel, + __private const int2 kernel_shape, + __private const int ic_h_w_size, + __private const int height_width_size, + __global char *output) { + int image_width_idx = get_global_id(0); // ic + int image_height_idx = get_global_id(1); // oc/4 h w + + DEAL_NON_UNIFORM_DIM2(image_width_idx, image_height_idx); + + const int input_channel_4_idx = image_width_idx; + const int output_channel_4_idx = (image_height_idx / height_width_size) * 4; + const int height_width_idx = image_height_idx % height_width_size; + const int buffer_height_idx = height_width_idx / kernel_shape.y; + const int buffer_width_idx = height_width_idx % kernel_shape.y; + + const int buffer_offset = output_channel_4_idx * ic_h_w_size + input_channel_4_idx * height_width_size + + buffer_height_idx * kernel_shape.y + buffer_width_idx; + + char4 output_values = 0; + if (output_channel_4_idx < output_channel) { + const int remain_channel = output_channel - output_channel_4_idx; + if (remain_channel >= 4) { + int offset = buffer_offset; + output_values.x = (char)(*(input_ptr + offset)); + offset = mad24(1, ic_h_w_size, offset); + output_values.y = (char)(*(input_ptr + offset)); + offset += ic_h_w_size; + output_values.z = (char)(*(input_ptr + offset)); + offset += ic_h_w_size; + output_values.w = (char)(*(input_ptr + offset)); + } else if (remain_channel == 3) { + int offset = buffer_offset; + output_values.x = (char)(*(input_ptr + offset)); + offset = mad24(1, ic_h_w_size, offset); + output_values.y = (char)(*(input_ptr + offset)); + offset += ic_h_w_size; + output_values.z = (char)(*(input_ptr + offset)); + + } else if (remain_channel == 2) { + int offset = buffer_offset; + output_values.x = (char)(*(input_ptr + offset)); + offset = mad24(1, ic_h_w_size, offset); + output_values.y = (char)(*(input_ptr + offset)); + } else if (remain_channel == 1) { + int offset = buffer_offset; + output_values.x = (char)(*(input_ptr + offset)); + } + } + const int out_offset = (image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*4; + vstore4(output_values, 0, output+out_offset); +} +#endif + +#ifdef USE_LOW_BIT_WEIGHT_INT4 +// convert kernel : from int8 buffer(oihw) to int4 image(oc/4 h w , ic oc4) +__kernel void conv2d_filter_buffer_to_nc4hw4_buffer_int4(GLOBAL_SIZE_2_DIMS + __global const char *input_ptr, + __private const int output_channel, + __private const int2 kernel_shape, + __private const int ic_h_w_size, + __private const int height_width_size, + __global uchar *output) { + int image_width_idx = get_global_id(0); // ic + int image_height_idx = get_global_id(1); // oc/4 h w + + DEAL_NON_UNIFORM_DIM2(image_width_idx, image_height_idx); + + const int input_channel_4_idx = image_width_idx; + const int output_channel_4_idx = (image_height_idx / height_width_size) * 4; + const int height_width_idx = image_height_idx % height_width_size; + const int buffer_height_idx = height_width_idx / kernel_shape.y; + const int buffer_width_idx = height_width_idx % kernel_shape.y; + + const int buffer_offset = output_channel_4_idx * ic_h_w_size + input_channel_4_idx * height_width_size + + buffer_height_idx * kernel_shape.y + buffer_width_idx; + + char4 output_values_int8 = 0; + if (output_channel_4_idx < output_channel) { + const int remain_channel = output_channel - output_channel_4_idx; + if (remain_channel >= 4) { + int offset = buffer_offset; + output_values_int8.x = (char)(*(input_ptr + offset)); + offset = mad24(1, ic_h_w_size, offset); + output_values_int8.y = (char)(*(input_ptr + offset)); + offset += ic_h_w_size; + output_values_int8.z = (char)(*(input_ptr + offset)); + offset += ic_h_w_size; + output_values_int8.w = (char)(*(input_ptr + offset)); + } else if (remain_channel == 3) { + int offset = buffer_offset; + output_values_int8.x = (char)(*(input_ptr + offset)); + offset = mad24(1, ic_h_w_size, offset); + output_values_int8.y = (char)(*(input_ptr + offset)); + offset += ic_h_w_size; + output_values_int8.z = (char)(*(input_ptr + offset)); + + } else if (remain_channel == 2) { + int offset = buffer_offset; + output_values_int8.x = (char)(*(input_ptr + offset)); + offset = mad24(1, ic_h_w_size, offset); + output_values_int8.y = (char)(*(input_ptr + offset)); + } else if (remain_channel == 1) { + int offset = buffer_offset; + output_values_int8.x = (char)(*(input_ptr + offset)); + } + } + + uchar2 output_values_int4 = (uchar2)(0, 0); + output_values_int4.s0 = (output_values_int8.x + 8) * 16 + (output_values_int8.y + 8); + output_values_int4.s1 = (output_values_int8.z + 8) * 16 + (output_values_int8.w + 8); + + const int out_offset = (image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*2; + vstore2(output_values_int4, 0, output+out_offset); +} +#endif + +#define CHAR16_TO_UCHAR8(a, b) \ + a = (uchar8)(((b.s0 + 8) << 4) + b.s1 + 8, ((b.s2 + 8) << 4) + b.s3 + 8, ((b.s4 + 8) << 4) + b.s5 + 8, ((b.s6 + 8) << 4) + b.s7 + 8, ((b.s8 + 8) << 4) + b.s9 + 8, ((b.sa + 8) << 4) + b.sb + 8, ((b.sc + 8) << 4) + b.sd + 8, ((b.se + 8) << 4) + b.sf + 8); + +#define CHAR32_TO_UCHAR16(a, b, c) \ + a = (uchar16)(((b.s0 + 8) << 4) + b.s1 + 8, ((b.s2 + 8) << 4) + b.s3 + 8, ((b.s4 + 8) << 4) + b.s5 + 8, ((b.s6 + 8) << 4) + b.s7 + 8, ((b.s8 + 8) << 4) + b.s9 + 8, ((b.sa + 8) << 4) + b.sb + 8, ((b.sc + 8) << 4) + b.sd + 8, ((b.se + 8) << 4) + b.sf + 8, \ + ((c.s0 + 8) << 4) + c.s1 + 8, ((c.s2 + 8) << 4) + c.s3 + 8, ((c.s4 + 8) << 4) + c.s5 + 8, ((c.s6 + 8) << 4) + c.s7 + 8, ((c.s8 + 8) << 4) + c.s9 + 8, ((c.sa + 8) << 4) + c.sb + 8, ((c.sc + 8) << 4) + c.sd + 8, ((c.se + 8) << 4) + c.sf + 8); +__kernel void conv2d_1x1_weight_quant_buffer(GLOBAL_SIZE_2_DIMS + __global const char *input_ptr, +#ifdef USE_LOW_BIT_WEIGHT_INT4 + __global uchar *output_ptr, +#else + __global char *output_ptr, +#endif + __private const int input_channel, + __private const int output_channel) { + int x = get_global_id(0); // ic / 16 + int y = get_global_id(1); // oc + + DEAL_NON_UNIFORM_DIM2(x, y); + const int xin = x << 4; + const int outputChannelC4 = (output_channel + 3) >> 2; + const int inputOffset = y * input_channel + xin; + char16 weight = 0; +#ifdef INPUT_CHANNEL_LEAVE + if(xin + 15 >= input_channel){ + char *weight_ptr = (char*)&weight; + for(int i = 0, j = 0; xin + i < input_channel && j < 16; ++i, ++j){ + weight_ptr[j] = input_ptr[inputOffset + i]; + } + }else { + weight = vload16(0, input_ptr + inputOffset); + } +#else + weight = vload16(0, input_ptr + inputOffset); +#endif + +#ifdef USE_LOW_BIT_WEIGHT_INT4 + const int outputOffset = ((x * outputChannelC4 * 4 * 8 + y * 8)); + uchar8 outWeight; + CHAR16_TO_UCHAR8(outWeight, weight); + vstore8(outWeight, 0, output_ptr + outputOffset); +#else + const int outputOffset = (x * outputChannelC4 * 4 + y) << 4; + vstore16(weight, 0, output_ptr + outputOffset); +#endif +} + +__kernel void conv2d_1x1_weight_quant_image(GLOBAL_SIZE_2_DIMS + __global const char *input_ptr, + __write_only image2d_t output, + __private const int input_channel, + __private const int output_channel) { + +#ifdef USE_LOW_BIT_WEIGHT_INT4 + int x = get_global_id(0); // ic / 32 + int y = get_global_id(1); // oc + + DEAL_NON_UNIFORM_DIM2(x, y); + const int outputChannelC4 = (output_channel + 3) >> 2; + const int xin = x << 5; + const int inputOffset = y * input_channel + xin; + char16 weight00 = 0, weight01 = 0; +#ifdef INPUT_CHANNEL_LEAVE + if(xin + 31 >= input_channel){ + char *weight00_ptr = (char*)&weight00; + char *weight01_ptr = (char*)&weight01; + int i = 0; + for(int j = 0; xin + i < input_channel && j < 16; ++i, ++j){ + weight00_ptr[j] = input_ptr[inputOffset + i]; + } + for(int j = 0; xin + i < input_channel && j < 16; ++i, ++j){ + weight01_ptr[j] = input_ptr[inputOffset + i]; + } + }else { + weight00 = vload16(0, input_ptr + inputOffset); + weight01 = vload16(0, input_ptr + inputOffset + 16); + } +#else + weight00 = vload16(0, input_ptr + inputOffset); + weight01 = vload16(0, input_ptr + inputOffset + 16); +#endif + + uchar16 outWeight; + CHAR32_TO_UCHAR16(outWeight, weight00, weight01); + write_imagei(output, (int2)(y, x), as_int4(outWeight)); +#else + int x = get_global_id(0); // ic / 16 + int y = get_global_id(1); // oc + + DEAL_NON_UNIFORM_DIM2(x, y); + const int xin = x << 4; + const int inputOffset = y * input_channel + xin; + const int outputChannelC4 = (output_channel + 3) >> 2; + char16 weight = 0; +#ifdef INPUT_CHANNEL_LEAVE + if(xin + 15 >= input_channel){ + char *weight_ptr = (char*)&weight; + for(int i = 0, j = 0; xin + i < input_channel && j < 16; ++i, ++j){ + weight_ptr[j] = input_ptr[inputOffset + i]; + } + }else { + weight = vload16(0, input_ptr + inputOffset); + } +#else + weight = vload16(0, input_ptr + inputOffset); +#endif + + write_imagei(output, (int2)(y, x), as_int4(weight)); +#endif +} diff --git a/source/backend/opencl/execution/cl/conv_2d.cl b/source/backend/opencl/execution/cl/conv_2d.cl index c3a807cb7..2b0bbad14 100644 --- a/source/backend/opencl/execution/cl/conv_2d.cl +++ b/source/backend/opencl/execution/cl/conv_2d.cl @@ -45,6 +45,16 @@ __constant sampler_t SAMPLER = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | #define UNIT 4 #define MOD_NUM 15 +#ifdef INPUT_CHANNEL_LEAVE + #define PADZEROSVEC(k, channel, data0, data1, data2, data3) \ + data0 = (k << 2) < channel ? data0 : 0; \ + data1 = (k << 2) + 1 < channel ? data1 : 0; \ + data2 = (k << 2) + 2 < channel ? data2 : 0; \ + data3 = (k << 2) + 3 < channel ? data3 : 0; +#else + #define PADZEROSVEC(k, channel, data0, data1, data2, data3) +#endif + __kernel #if SET_ATTRIBUTE __attribute__((work_group_size_hint(16, 16, 1))) @@ -184,12 +194,10 @@ __attribute__((work_group_size_hint(16, 16, 1))) void conv_2d_1x1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) __global const char *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_BUFFER) __global const FLOAT *weights, #else @@ -201,7 +209,12 @@ void conv_2d_1x1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, __private const int in_channel_block, __private const int2 output_shape, __private const int2 stride_shape, __private const int output_width_4, - __private const int out_channel_blocks) { + __private const int out_channel_blocks +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + ,__private const int blockDim + ,__private const int inChannel +#endif +) { const int output_channel_width_idx = get_global_id(0); const int output_batch_height_idx = get_global_id(1); @@ -240,11 +253,6 @@ void conv_2d_1x1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, intput_width_idx3 = select(intput_width_idx3, INT_MIN, intput_width_idx3 >= input_shape.y); #endif -#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) - const FLOAT4 dequantScaleC4 = vload4(output_channel_block_idx, dequantScale); - const FLOAT4 dequantOffsetC4 = vload4(output_channel_block_idx, dequantOffset); -#endif - int batch_index = output_batch_height_idx / output_shape.x; int input_height_block_idx = mul24((output_batch_height_idx % output_shape.x), stride_shape.x) + batch_index * input_shape.x; @@ -259,15 +267,21 @@ void conv_2d_1x1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, int weight_offset = output_channel_block_idx * in_channel_block * 4 * 4; for (int in_channel_block_idx = 0; in_channel_block_idx < in_channel_block; ++in_channel_block_idx) { +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + int kindex = (in_channel_block_idx * 4) / blockDim * out_channel_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(output_channel_block_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); +#endif int input_width_base = in_channel_block_idx * input_shape.y; int weights_width_base = in_channel_block_idx << 2; #if (defined USE_LOW_BIT_WEIGHT_INT8) FLOAT16 weights = CONVERT_FLOAT16(vload16(0, kernel_ptr + weight_ic_offset + in_channel_block_idx * weight_oc_offset)); - FLOAT4 weights0 = CONVERT_FLOAT4(weights.s0123) * dequantScaleC4 + dequantOffsetC4; - FLOAT4 weights1 = CONVERT_FLOAT4(weights.s4567) * dequantScaleC4 + dequantOffsetC4; - FLOAT4 weights2 = CONVERT_FLOAT4(weights.s89ab) * dequantScaleC4 + dequantOffsetC4; - FLOAT4 weights3 = CONVERT_FLOAT4(weights.scdef) * dequantScaleC4 + dequantOffsetC4; + FLOAT4 weights0 = CONVERT_FLOAT4(weights.s0123) * scale0 + offset0; + FLOAT4 weights1 = CONVERT_FLOAT4(weights.s4567) * scale0 + offset0; + FLOAT4 weights2 = CONVERT_FLOAT4(weights.s89ab) * scale0 + offset0; + FLOAT4 weights3 = CONVERT_FLOAT4(weights.scdef) * scale0 + offset0; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar8 charWeightsInt4 = vload8(0, kernel_ptr + weight_ic_offset + in_channel_block_idx * weight_oc_offset); char4 charWeights0 = (char4)(0, 0, 0, 0); @@ -290,10 +304,10 @@ void conv_2d_1x1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeights3.y = (charWeightsInt4.s6 & MOD_NUM) - 8; charWeights3.z = (charWeightsInt4.s7 >> 4) - 8; charWeights3.w = (charWeightsInt4.s7 & MOD_NUM) - 8; - weights0 = mad(CONVERT_FLOAT4(charWeights0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeights1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeights2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeights3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeights0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeights1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeights2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeights3), scale0, offset0); #elif (defined USE_BUFFER) weights0 = vload4(weights_width_base, weights + weight_offset); weights1 = vload4(weights_width_base + 1, weights + weight_offset); @@ -305,6 +319,7 @@ void conv_2d_1x1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, weights2 = RI_F(weights, SAMPLER, (int2)(weights_width_base + 2, output_channel_block_idx)); weights3 = RI_F(weights, SAMPLER, (int2)(weights_width_base + 3, output_channel_block_idx)); #endif + PADZEROSVEC(in_channel_block_idx, inChannel, weights0, weights1, weights2, weights3); in0 = RI_F(input, SAMPLER, (int2)(input_width_base + intput_width_idx0, input_height_block_idx)); in1 = RI_F(input, SAMPLER, (int2)(input_width_base + intput_width_idx1, input_height_block_idx)); in2 = RI_F(input, SAMPLER, (int2)(input_width_base + intput_width_idx2, input_height_block_idx)); @@ -359,12 +374,10 @@ __attribute__((work_group_size_hint(16, 16, 1))) void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) __global const char *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_BUFFER) __global const FLOAT *weights, #else @@ -376,7 +389,12 @@ void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, __private const int in_channel_block, __private const int2 output_shape, __private const int2 stride_shape, __private const int output_width_4, - __private const int out_channel_blocks) { + __private const int out_channel_blocks +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + ,__private const int blockDim + ,__private const int inChannel +#endif +) { const int output_channel_width_idx = get_global_id(0); const int output_batch_height_idx = get_global_id(1); @@ -420,13 +438,6 @@ void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, intput_width_idx3 = select(intput_width_idx3, INT_MIN, intput_width_idx3 >= input_shape.y); #endif -#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) - const FLOAT4 dequantScaleC03 = vload4(output_channel_idx, dequantScale); - const FLOAT4 dequantOffsetC03 = vload4(output_channel_idx, dequantOffset); - const FLOAT4 dequantScaleC47 = vload4(output_channel_idx + 1, dequantScale); - const FLOAT4 dequantOffsetC47 = vload4(output_channel_idx + 1, dequantOffset); -#endif - int batch_index = output_batch_height_idx / output_shape.x; int input_height_block_idx = mul24((output_batch_height_idx % output_shape.x), stride_shape.x) + batch_index * input_shape.x; @@ -446,6 +457,16 @@ void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, int weight_offset1 = weight_offset + in_channel_block * 4 * 4; for (int in_channel_block_idx = 0; in_channel_block_idx < in_channel_block; ++in_channel_block_idx) { +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + int kindex = (in_channel_block_idx * 4) / blockDim * out_channel_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(output_channel_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); + COMPUTE_FLOAT8 ScaleOffset1 = CONVERT_COMPUTE_FLOAT8(vload8(output_channel_idx + 1, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale1 = (COMPUTE_FLOAT4)(ScaleOffset1.s0, ScaleOffset1.s2, ScaleOffset1.s4, ScaleOffset1.s6); + COMPUTE_FLOAT4 offset1 = (COMPUTE_FLOAT4)(ScaleOffset1.s1, ScaleOffset1.s3, ScaleOffset1.s5, ScaleOffset1.s7); +#endif + int input_width_base = in_channel_block_idx * input_shape.y; int weights_width_base = in_channel_block_idx << 2; in0 = RI_F(input, SAMPLER, (int2)(input_width_base + intput_width_idx0, input_height_block_idx)); @@ -456,14 +477,14 @@ void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) FLOAT16 weightsInt80 = CONVERT_FLOAT16(vload16(0, kernel_ptr + weight_ic_offset + in_channel_block_idx * weight_oc_offset)); FLOAT16 weightsInt81 = CONVERT_FLOAT16(vload16(0, kernel_ptr + 16 + weight_ic_offset + in_channel_block_idx * weight_oc_offset)); - FLOAT4 weights0 = CONVERT_FLOAT4(weightsInt80.s0123) * dequantScaleC03 + dequantOffsetC03; - FLOAT4 weights1 = CONVERT_FLOAT4(weightsInt80.s4567) * dequantScaleC03 + dequantOffsetC03; - FLOAT4 weights2 = CONVERT_FLOAT4(weightsInt80.s89ab) * dequantScaleC03 + dequantOffsetC03; - FLOAT4 weights3 = CONVERT_FLOAT4(weightsInt80.scdef) * dequantScaleC03 + dequantOffsetC03; - FLOAT4 weights4 = CONVERT_FLOAT4(weightsInt81.s0123) * dequantScaleC47 + dequantOffsetC47; - FLOAT4 weights5 = CONVERT_FLOAT4(weightsInt81.s4567) * dequantScaleC47 + dequantOffsetC47; - FLOAT4 weights6 = CONVERT_FLOAT4(weightsInt81.s89ab) * dequantScaleC47 + dequantOffsetC47; - FLOAT4 weights7 = CONVERT_FLOAT4(weightsInt81.scdef) * dequantScaleC47 + dequantOffsetC47; + FLOAT4 weights0 = CONVERT_FLOAT4(weightsInt80.s0123) * scale0 + offset0; + FLOAT4 weights1 = CONVERT_FLOAT4(weightsInt80.s4567) * scale0 + offset0; + FLOAT4 weights2 = CONVERT_FLOAT4(weightsInt80.s89ab) * scale0 + offset0; + FLOAT4 weights3 = CONVERT_FLOAT4(weightsInt80.scdef) * scale0 + offset0; + FLOAT4 weights4 = CONVERT_FLOAT4(weightsInt81.s0123) * scale1 + offset1; + FLOAT4 weights5 = CONVERT_FLOAT4(weightsInt81.s4567) * scale1 + offset1; + FLOAT4 weights6 = CONVERT_FLOAT4(weightsInt81.s89ab) * scale1 + offset1; + FLOAT4 weights7 = CONVERT_FLOAT4(weightsInt81.scdef) * scale1 + offset1; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar16 charWeightsInt4 = vload16(0, kernel_ptr + weight_ic_offset + in_channel_block_idx * weight_oc_offset); char4 charWeights0 = (char4)(0, 0, 0, 0); @@ -506,14 +527,14 @@ void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeights7.y = (charWeightsInt4.se & MOD_NUM) - 8; charWeights7.z = (charWeightsInt4.sf >> 4) - 8; charWeights7.w = (charWeightsInt4.sf & MOD_NUM) - 8; - weights0 = mad(CONVERT_FLOAT4(charWeights0), dequantScaleC03, dequantOffsetC03); - weights1 = mad(CONVERT_FLOAT4(charWeights1), dequantScaleC03, dequantOffsetC03); - weights2 = mad(CONVERT_FLOAT4(charWeights2), dequantScaleC03, dequantOffsetC03); - weights3 = mad(CONVERT_FLOAT4(charWeights3), dequantScaleC03, dequantOffsetC03); - weights4 = mad(CONVERT_FLOAT4(charWeights4), dequantScaleC47, dequantOffsetC47); - weights5 = mad(CONVERT_FLOAT4(charWeights5), dequantScaleC47, dequantOffsetC47); - weights6 = mad(CONVERT_FLOAT4(charWeights6), dequantScaleC47, dequantOffsetC47); - weights7 = mad(CONVERT_FLOAT4(charWeights7), dequantScaleC47, dequantOffsetC47); + weights0 = mad(CONVERT_FLOAT4(charWeights0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeights1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeights2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeights3), scale0, offset0); + weights4 = mad(CONVERT_FLOAT4(charWeights4), scale1, offset1); + weights5 = mad(CONVERT_FLOAT4(charWeights5), scale1, offset1); + weights6 = mad(CONVERT_FLOAT4(charWeights6), scale1, offset1); + weights7 = mad(CONVERT_FLOAT4(charWeights7), scale1, offset1); #elif (defined USE_BUFFER) weights0 = vload4(weights_width_base, weights + weight_offset); weights1 = vload4(weights_width_base + 1, weights + weight_offset); @@ -535,6 +556,8 @@ void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, weights6 = RI_F(weights, SAMPLER, (int2)(weights_width_base + 2, output_channel_idx + 1)); weights7 = RI_F(weights, SAMPLER, (int2)(weights_width_base + 3, output_channel_idx + 1)); #endif + PADZEROSVEC(in_channel_block_idx, inChannel, weights0, weights1, weights2, weights3); + PADZEROSVEC(in_channel_block_idx, inChannel, weights4, weights5, weights6, weights7); CALCULATE_OUTPUT(0); CALCULATE_OUTPUT(1); @@ -617,12 +640,10 @@ __attribute__((work_group_size_hint(16, 16, 1))) void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) __global const char *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_BUFFER) __global const FLOAT *weights, #else @@ -641,7 +662,12 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, __private const int2 dilation_shape, __private const int out_width_blocks, __private const int out_channel_blocks, - __private const int out_height_blocks) { + __private const int out_height_blocks +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + ,__private const int blockDim + ,__private const int inChannel +#endif +) { const int output_channel_width_idx = get_global_id(0); const int output_batch_height_idx = get_global_id(1); @@ -683,14 +709,20 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, #endif #if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER) - const FLOAT4 dequantScaleC4 = vload4(out_channel_block_idx, dequantScale); - const FLOAT4 dequantOffsetC4 = vload4(out_channel_block_idx, dequantOffset); const int weight_oc_offset = out_channel_blocks * weights_shape.x * weights_shape.y * 4; #endif FLOAT4 in0, in1, in2, in3; FLOAT4 weights0, weights1, weights2, weights3; for (int in_channel_block_idx = 0; in_channel_block_idx < in_channel_block_length; ++in_channel_block_idx) { + +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + int kindex = (in_channel_block_idx * 4) / blockDim * out_channel_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(out_channel_block_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); +#endif + const int in_idx = mul24(in_channel_block_idx, input_shape.y); #if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER) int weight_offset = ((((4*in_channel_block_idx+0)* out_channel_blocks + out_channel_block_idx) *weights_shape.x + kh_start)*weights_shape.y + 0) * 4; @@ -712,10 +744,10 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, char4 charWeight1 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*3); - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar2 charWeightInt40 = vload2(0, kernel_ptr+weight_offset/2); @@ -742,10 +774,10 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_BUFFER) weights0 = vload4(0, weights+weight_offset); @@ -759,6 +791,7 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, weights2 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 2, weights_y_idx)); weights3 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 3, weights_y_idx++)); #endif + PADZEROSVEC(in_channel_block_idx, inChannel, weights0, weights1, weights2, weights3); CALCULATE_OUTPUT(0); CALCULATE_OUTPUT(1); CALCULATE_OUTPUT(2); @@ -774,10 +807,10 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, char4 charWeight1 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*3); - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar2 charWeightInt40 = vload2(0, kernel_ptr+weight_offset/2); @@ -804,10 +837,10 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_BUFFER) weights0 = vload4(0, weights+weight_offset); @@ -821,6 +854,7 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, weights2 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 2, weights_y_idx)); weights3 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 3, weights_y_idx++)); #endif + PADZEROSVEC(in_channel_block_idx, inChannel, weights0, weights1, weights2, weights3); CALCULATE_OUTPUT(0); CALCULATE_OUTPUT(1); CALCULATE_OUTPUT(2); @@ -838,10 +872,10 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, char4 charWeight1 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*3); - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar2 charWeightInt40 = vload2(0, kernel_ptr+weight_offset/2); @@ -868,10 +902,10 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_BUFFER) weights0 = vload4(0, weights+weight_offset); @@ -885,6 +919,7 @@ void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, weights2 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 2, weights_y_idx)); weights3 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 3, weights_y_idx++)); #endif + PADZEROSVEC(in_channel_block_idx, inChannel, weights0, weights1, weights2, weights3); CALCULATE_OUTPUT(0); CALCULATE_OUTPUT(1); CALCULATE_OUTPUT(2); @@ -937,12 +972,10 @@ __attribute__((work_group_size_hint(16, 16, 1))) void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) __global const char *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_BUFFER) __global const FLOAT *weights, #else @@ -961,7 +994,12 @@ void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, __private const int2 dilation_shape, __private const int out_width_blocks, __private const int out_channel_blocks, - __private const int out_height_blocks) { + __private const int out_height_blocks +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + ,__private const int blockDim + ,__private const int inChannel +#endif +) { const int output_channel_width_idx = get_global_id(0); const int output_batch_height_idx = get_global_id(1); @@ -987,10 +1025,6 @@ void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, FLOAT4 out7 = out4; #if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER) - const FLOAT4 dequantScaleC03 = vload4(out_channel_block_idx, dequantScale); - const FLOAT4 dequantOffsetC03 = vload4(out_channel_block_idx, dequantOffset); - const FLOAT4 dequantScaleC47 = vload4(out_channel_block_idx + 1, dequantScale); - const FLOAT4 dequantOffsetC47 = vload4(out_channel_block_idx + 1, dequantOffset); const int weight_oc_offset = weights_shape.x * weights_shape.y * 4; const int weight_ic_offset = out_channel_blocks * weight_oc_offset; #endif @@ -1008,6 +1042,16 @@ void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, FLOAT4 in0, in1, in2, in3; FLOAT4 weights0, weights1, weights2, weights3, weights4, weights5, weights6, weights7; for (int in_channel_block_idx = 0; in_channel_block_idx < in_channel_block_length; ++in_channel_block_idx) { +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + int kindex = (in_channel_block_idx * 4) / blockDim * out_channel_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(out_channel_block_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); + COMPUTE_FLOAT8 ScaleOffset1 = CONVERT_COMPUTE_FLOAT8(vload8(out_channel_block_idx + 1, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale1 = (COMPUTE_FLOAT4)(ScaleOffset1.s0, ScaleOffset1.s2, ScaleOffset1.s4, ScaleOffset1.s6); + COMPUTE_FLOAT4 offset1 = (COMPUTE_FLOAT4)(ScaleOffset1.s1, ScaleOffset1.s3, ScaleOffset1.s5, ScaleOffset1.s7); + +#endif const int in_idx = mul24(in_channel_block_idx, input_shape.y); #if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER) int weight_offset = ((((4*in_channel_block_idx+0)* out_channel_blocks + out_channel_block_idx) *weights_shape.x + 0)*weights_shape.y + 0) * 4; @@ -1033,18 +1077,18 @@ void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, char4 charWeight1 = vload4(0, kernel_ptr+weight_offset+weight_ic_offset); char4 charWeight2 = vload4(0, kernel_ptr+weight_offset+weight_ic_offset*2); char4 charWeight3 = vload4(0, kernel_ptr+weight_offset+weight_ic_offset*3); - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC03, dequantOffsetC03); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC03, dequantOffsetC03); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC03, dequantOffsetC03); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC03, dequantOffsetC03); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); charWeight0 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset); charWeight1 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset+weight_ic_offset); charWeight2 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset+weight_ic_offset*2); charWeight3 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset+weight_ic_offset*3); - weights4 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC47, dequantOffsetC47); - weights5 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC47, dequantOffsetC47); - weights6 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC47, dequantOffsetC47); - weights7 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC47, dequantOffsetC47); + weights4 = mad(CONVERT_FLOAT4(charWeight0), scale1, offset1); + weights5 = mad(CONVERT_FLOAT4(charWeight1), scale1, offset1); + weights6 = mad(CONVERT_FLOAT4(charWeight2), scale1, offset1); + weights7 = mad(CONVERT_FLOAT4(charWeight3), scale1, offset1); weight_offset += 4; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar2 charWeightInt40 = vload2(0, kernel_ptr+weight_offset/2); @@ -1071,10 +1115,10 @@ void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC03, dequantOffsetC03); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC03, dequantOffsetC03); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC03, dequantOffsetC03); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC03, dequantOffsetC03); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); charWeightInt40 = vload2(0, kernel_ptr+weight_offset/2+weight_oc_offset/2); charWeightInt41 = vload2(0, kernel_ptr+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2); charWeightInt42 = vload2(0, kernel_ptr+weight_offset/2+weight_oc_offset/2+weight_ic_offset*2/2); @@ -1099,10 +1143,10 @@ void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weights4 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC47, dequantOffsetC47); - weights5 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC47, dequantOffsetC47); - weights6 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC47, dequantOffsetC47); - weights7 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC47, dequantOffsetC47); + weights4 = mad(CONVERT_FLOAT4(charWeight0), scale1, offset1); + weights5 = mad(CONVERT_FLOAT4(charWeight1), scale1, offset1); + weights6 = mad(CONVERT_FLOAT4(charWeight2), scale1, offset1); + weights7 = mad(CONVERT_FLOAT4(charWeight3), scale1, offset1); weight_offset += 4; #elif (defined USE_BUFFER) weights0 = vload4(0, weights+weight_offset); @@ -1124,6 +1168,8 @@ void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, weights6 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 2, weight_size + weights_y_idx)); weights7 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 3, weight_size + weights_y_idx++)); #endif + PADZEROSVEC(in_channel_block_idx, inChannel, weights0, weights1, weights2, weights3); + PADZEROSVEC(in_channel_block_idx, inChannel, weights4, weights5, weights6, weights7); CALCULATE_OUTPUT(0); CALCULATE_OUTPUT(1); @@ -1212,12 +1258,10 @@ __attribute__((work_group_size_hint(16, 16, 1))) void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) __global const char *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *kernel_ptr, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_BUFFER) __global const FLOAT *weights, #else @@ -1236,7 +1280,12 @@ void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, __private const int2 dilation_shape, __private const int out_width_blocks, __private const int out_channel_blocks, - __private const int out_height_blocks) { + __private const int out_height_blocks +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + ,__private const int blockDim + ,__private const int inChannel +#endif +) { const int output_channel_width_idx = get_global_id(0); const int output_batch_height_idx = get_global_id(1); @@ -1269,11 +1318,15 @@ void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, FLOAT4 in0, in1, in2, in3; FLOAT4 weights0, weights1, weights2, weights3; #if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER) - const FLOAT4 dequantScaleC4 = vload4(out_channel_block_idx, dequantScale); - const FLOAT4 dequantOffsetC4 = vload4(out_channel_block_idx, dequantOffset); const int weight_oc_offset = out_channel_blocks * weights_shape.x * weights_shape.y * 4; #endif for (int in_channel_block_idx = 0; in_channel_block_idx < in_channel_block_length; ++in_channel_block_idx) { +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + int kindex = (in_channel_block_idx * 4) / blockDim * out_channel_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(out_channel_block_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); +#endif const int in_idx = mul24(in_channel_block_idx, input_shape.y); #if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER) int weight_offset = ((((4*in_channel_block_idx+0)* out_channel_blocks + out_channel_block_idx) *weights_shape.x + 0)*weights_shape.y + 0) * 4; @@ -1299,10 +1352,10 @@ void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, char4 charWeight1 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(0, kernel_ptr+weight_offset+weight_oc_offset*3); - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar2 charWeightInt40 = vload2(0, kernel_ptr+weight_offset/2); @@ -1329,10 +1382,10 @@ void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weights0 = mad(CONVERT_FLOAT4(charWeight0), dequantScaleC4, dequantOffsetC4); - weights1 = mad(CONVERT_FLOAT4(charWeight1), dequantScaleC4, dequantOffsetC4); - weights2 = mad(CONVERT_FLOAT4(charWeight2), dequantScaleC4, dequantOffsetC4); - weights3 = mad(CONVERT_FLOAT4(charWeight3), dequantScaleC4, dequantOffsetC4); + weights0 = mad(CONVERT_FLOAT4(charWeight0), scale0, offset0); + weights1 = mad(CONVERT_FLOAT4(charWeight1), scale0, offset0); + weights2 = mad(CONVERT_FLOAT4(charWeight2), scale0, offset0); + weights3 = mad(CONVERT_FLOAT4(charWeight3), scale0, offset0); weight_offset += 4; #elif (defined USE_BUFFER) weights0 = vload4(0, weights+weight_offset); @@ -1346,6 +1399,7 @@ void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input, weights2 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 2, weights_y_idx)); weights3 = RI_F(weights, SAMPLER, (int2)(weights_x_idx + 3, weights_y_idx++)); #endif + PADZEROSVEC(in_channel_block_idx, inChannel, weights0, weights1, weights2, weights3); CALCULATE_OUTPUT(0); CALCULATE_OUTPUT(1); diff --git a/source/backend/opencl/execution/cl/conv_2d_int_buf.cl b/source/backend/opencl/execution/cl/conv_2d_int_buf.cl index c2342b6d4..aeed184ce 100644 --- a/source/backend/opencl/execution/cl/conv_2d_int_buf.cl +++ b/source/backend/opencl/execution/cl/conv_2d_int_buf.cl @@ -10,7 +10,15 @@ } #define MOD_NUM 15 - +#ifdef INPUT_CHANNEL_LEAVE + #define PADZEROSVEC(k, channel, data0, data1, data2, data3) \ + data0 = (k << 2) < channel ? data0 : 0; \ + data1 = (k << 2) + 1 < channel ? data1 : 0; \ + data2 = (k << 2) + 2 < channel ? data2 : 0; \ + data3 = (k << 2) + 3 < channel ? data3 : 0; +#else + #define PADZEROSVEC(k, channel, data0, data1, data2, data3) +#endif __kernel void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS @@ -20,8 +28,7 @@ void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS #else __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT *output, __private const int2 in_hw, @@ -34,7 +41,8 @@ void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS __private const int2 dilate_hw, __private const int out_w_blocks, __private const int out_c_blocks, - __private const int out_h_blocks) { + __private const int out_h_blocks, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -45,12 +53,7 @@ void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS const int out_b_idx = out_b_h_idx / out_hw.x;//equal to in_b_idx const int out_h_idx = out_b_h_idx % out_hw.x; - const float4 dequantScaleC4 = vload4(out_c_idx, dequantScale); - const float4 dequantOffsetC4 = vload4(out_c_idx, dequantOffset); - - COMPUTE_FLOAT4 vbias = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT4 out0 = (COMPUTE_FLOAT)0; - COMPUTE_FLOAT sum = (COMPUTE_FLOAT)0; + COMPUTE_FLOAT4 out0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); const int in_w_idx_base = mad24(out_w_idx, stride_hw.y, -pad_hw.y); const int in_h_idx_base = mad24(out_h_idx, stride_hw.x, -pad_hw.x); @@ -65,6 +68,10 @@ void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS const int weight_oc_offset = out_c_blocks * filter_hw.x * filter_hw.y * 4; for(ushort in_c_idx = 0; in_c_idx < in_c_blocks; in_c_idx++) { + int kindex = (in_c_idx * 4) / blockDim * out_c_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale = (COMPUTE_FLOAT4)(ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6); + COMPUTE_FLOAT4 offset = (COMPUTE_FLOAT4)(ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7); //weights NC4HW4 [1, 4*icC4, ocC4*kh*kw, 1] xic4 //index: [0, 4*in_c_idx, out_c_idx*kh*kw + kh_start*kw + kw_start, 0] int weight_offset = ((((4*in_c_idx+0)* out_c_blocks + out_c_idx) *filter_hw.x + kh_start)*filter_hw.y + kw_start) * 4; @@ -80,10 +87,10 @@ void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS char4 charWeight1 = vload4(filter_w_inc, weight+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(filter_w_inc, weight+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(filter_w_inc, weight+weight_offset+weight_oc_offset*3); - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #else uchar2 charWeightInt40 = vload2(filter_w_inc, weight+weight_offset/2); uchar2 charWeightInt41 = vload2(filter_w_inc, weight+weight_offset/2+weight_oc_offset/2); @@ -109,12 +116,13 @@ void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #endif - sum += (in0.x + in0.y + in0.z + in0.w); + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); + out0 = mad(in0.x, weight0, out0); out0 = mad(in0.y, weight1, out0); out0 = mad(in0.z, weight2, out0); @@ -125,8 +133,6 @@ void conv_2d_int_c4h1w1(GLOBAL_SIZE_2_DIMS } } - out0 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out0) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum) * dequantOffsetC4); - #ifdef RELU out0 = fmax(out0, (COMPUTE_FLOAT4)0); #endif @@ -148,8 +154,7 @@ void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS #else __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT *output, __private const int2 in_hw, @@ -162,7 +167,8 @@ void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS __private const int2 dilate_hw, __private const int out_w_blocks,//generate width's num __private const int out_c_blocks, - __private const int out_h_blocks) { + __private const int out_h_blocks, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -173,14 +179,9 @@ void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS const int out_b_idx = out_b_h_idx / out_hw.x;//equal to in_b_idx const int out_h_idx = out_b_h_idx % out_hw.x; - const float4 dequantScaleC4 = vload4(out_c_idx, dequantScale); - const float4 dequantOffsetC4 = vload4(out_c_idx, dequantOffset); - - COMPUTE_FLOAT4 vbias = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT4 out0 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out1 = out0; - COMPUTE_FLOAT sum0 = 0; - COMPUTE_FLOAT sum1 = 0; + COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); + COMPUTE_FLOAT4 out0 = bias0; + COMPUTE_FLOAT4 out1 = bias0; const int in_w0_idx_base = mad24(out_w_idx, stride_hw.y, -pad_hw.y); const int in_w1_idx_base = in_w0_idx_base + stride_hw.y; @@ -193,6 +194,10 @@ void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS const int weight_oc_offset = out_c_blocks * filter_hw.x * filter_hw.y * 4; for(ushort in_c_idx = 0; in_c_idx < in_c_blocks; in_c_idx++) { + int kindex = (in_c_idx * 4) / blockDim * out_c_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale = (COMPUTE_FLOAT4)(ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6); + COMPUTE_FLOAT4 offset = (COMPUTE_FLOAT4)(ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7); //weights NC4HW4 [1, 4*icC4, ocC4*kh*kw, 1] xic4 //index: [0, 4*in_c_idx, out_c_idx*kh*kw + kh_start*kw + kw_start, 0] int weight_offset = ((((4*in_c_idx+0)* out_c_blocks + out_c_idx) *filter_hw.x + kh_start)*filter_hw.y + 0) * 4; @@ -212,10 +217,10 @@ void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS char4 charWeight1 = vload4(0, weight+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(0, weight+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(0, weight+weight_offset+weight_oc_offset*3); - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #else uchar2 charWeightInt40 = vload2(0, weight+weight_offset/2); uchar2 charWeightInt41 = vload2(0, weight+weight_offset/2+weight_oc_offset/2); @@ -241,15 +246,13 @@ void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #endif - - sum0 += (in0.x + in0.y + in0.z + in0.w); - sum1 += (in1.x + in1.y + in1.z + in1.w); - + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); + out0 = mad(in0.x, weight0, out0); out0 = mad(in0.y, weight1, out0); out0 = mad(in0.z, weight2, out0); @@ -265,9 +268,6 @@ void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS } } - out0 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out0) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC4); - out1 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out1) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC4); - #ifdef RELU out0 = fmax(out0, (COMPUTE_FLOAT4)0); out1 = fmax(out1, (COMPUTE_FLOAT4)0); @@ -296,8 +296,7 @@ void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS #else __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT *output, __private const int2 in_hw, @@ -310,7 +309,8 @@ void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS __private const int2 dilate_hw, __private const int out_w_blocks, __private const int out_c_blocks, - __private const int out_h_blocks) { + __private const int out_h_blocks, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -320,19 +320,12 @@ void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS const int out_w_idx = (out_c_w_idx % out_w_blocks) << 2; const int out_b_idx = out_b_h_idx / out_hw.x;//equal to in_b_idx const int out_h_idx = out_b_h_idx % out_hw.x; - - const float4 dequantScaleC4 = vload4(out_c_idx, dequantScale); - const float4 dequantOffsetC4 = vload4(out_c_idx, dequantOffset); - - COMPUTE_FLOAT4 vbias = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT4 out0 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out1 = out0; - COMPUTE_FLOAT4 out2 = out0; - COMPUTE_FLOAT4 out3 = out0; - COMPUTE_FLOAT sum0 = 0; - COMPUTE_FLOAT sum1 = 0; - COMPUTE_FLOAT sum2 = 0; - COMPUTE_FLOAT sum3 = 0; + + COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); + COMPUTE_FLOAT4 out0 = bias0; + COMPUTE_FLOAT4 out1 = bias0; + COMPUTE_FLOAT4 out2 = bias0; + COMPUTE_FLOAT4 out3 = bias0; const int in_w0_idx_base = mad24(out_w_idx, stride_hw.y, -pad_hw.y); const int in_w1_idx_base = in_w0_idx_base + stride_hw.y; @@ -347,6 +340,10 @@ void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS const int weight_oc_offset = out_c_blocks * filter_hw.x * filter_hw.y * 4; for(ushort in_c_idx = 0; in_c_idx < in_c_blocks; in_c_idx++) { + int kindex = (in_c_idx * 4) / blockDim * out_c_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale = (COMPUTE_FLOAT4)(ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6); + COMPUTE_FLOAT4 offset = (COMPUTE_FLOAT4)(ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7); //weights NC4HW4 [1, 4*icC4, ocC4*kh*kw, 1] xic4 //index: [0, 4*in_c_idx, out_c_idx*kh*kw + kh_start*kw + kw_start, 0] int weight_offset = ((((4*in_c_idx+0)* out_c_blocks + out_c_idx) *filter_hw.x + kh_start)*filter_hw.y + 0) * 4; @@ -370,10 +367,10 @@ void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS char4 charWeight1 = vload4(0, weight+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(0, weight+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(0, weight+weight_offset+weight_oc_offset*3); - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #else uchar2 charWeightInt40 = vload2(0, weight+weight_offset/2); uchar2 charWeightInt41 = vload2(0, weight+weight_offset/2+weight_oc_offset/2); @@ -399,16 +396,12 @@ void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #endif - - sum0 += (in0.x + in0.y + in0.z + in0.w); - sum1 += (in1.x + in1.y + in1.z + in1.w); - sum2 += (in2.x + in2.y + in2.z + in2.w); - sum3 += (in3.x + in3.y + in3.z + in3.w); + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out0 = mad(in0.x, weight0, out0); out0 = mad(in0.y, weight1, out0); @@ -434,10 +427,7 @@ void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS } } } - out0 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out0) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC4); - out1 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out1) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC4); - out2 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out2) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum2) * dequantOffsetC4); - out3 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out3) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum3) * dequantOffsetC4); + #ifdef RELU out0 = fmax(out0, (COMPUTE_FLOAT4)0); out1 = fmax(out1, (COMPUTE_FLOAT4)0); @@ -479,8 +469,7 @@ void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS #else __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT *output, __private const int2 in_hw, @@ -493,7 +482,8 @@ void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS __private const int2 dilate_hw, __private const int out_w_blocks, __private const int out_c_blocks, - __private const int out_h_blocks) { + __private const int out_h_blocks, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -504,18 +494,11 @@ void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS const int out_b_idx = out_b_h_idx / out_h_blocks;//equal to in_b_idx const int out_h_idx = (out_b_h_idx % out_h_blocks) << 2; - const float4 dequantScaleC4 = vload4(out_c_idx, dequantScale); - const float4 dequantOffsetC4 = vload4(out_c_idx, dequantOffset); - - COMPUTE_FLOAT4 vbias = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT4 out0 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out1 = out0; - COMPUTE_FLOAT4 out2 = out0; - COMPUTE_FLOAT4 out3 = out0; - COMPUTE_FLOAT sum0 = 0; - COMPUTE_FLOAT sum1 = 0; - COMPUTE_FLOAT sum2 = 0; - COMPUTE_FLOAT sum3 = 0; + COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); + COMPUTE_FLOAT4 out0 = bias0; + COMPUTE_FLOAT4 out1 = bias0; + COMPUTE_FLOAT4 out2 = bias0; + COMPUTE_FLOAT4 out3 = bias0; const int in_w_idx_base = mad24(out_w_idx, stride_hw.y, -pad_hw.y); @@ -531,6 +514,10 @@ void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS const int weight_oc_offset = out_c_blocks * filter_hw.x * filter_hw.y * 4; const int in_hw_size = in_hw.x * in_hw.y; for(ushort in_c_idx = 0; in_c_idx < in_c_blocks; in_c_idx++) { + int kindex = (in_c_idx * 4) / blockDim * out_c_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale = (COMPUTE_FLOAT4)(ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6); + COMPUTE_FLOAT4 offset = (COMPUTE_FLOAT4)(ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7); //weights NC4HW4 [1, 4*icC4, ocC4*kh*kw, 1] xic4 //index: [0, 4*in_c_idx, out_c_idx*kh*kw + kh_start*kw + kw_start, 0] const int inp_offset_base = (out_b_idx * in_c_blocks + in_c_idx) * in_hw.x * in_hw.y * 4; @@ -553,10 +540,10 @@ void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS char4 charWeight1 = vload4(0, weight+weight_offset+weight_oc_offset); char4 charWeight2 = vload4(0, weight+weight_offset+weight_oc_offset*2); char4 charWeight3 = vload4(0, weight+weight_offset+weight_oc_offset*3); - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #else uchar2 charWeightInt40 = vload2(0, weight+weight_offset/2); uchar2 charWeightInt41 = vload2(0, weight+weight_offset/2+weight_oc_offset/2); @@ -582,16 +569,12 @@ void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale + offset; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale + offset; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale + offset; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale + offset; #endif - - sum0 += (in0.x + in0.y + in0.z + in0.w); - sum1 += (in1.x + in1.y + in1.z + in1.w); - sum2 += (in2.x + in2.y + in2.z + in2.w); - sum3 += (in3.x + in3.y + in3.z + in3.w); + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out0 = mad(in0.x, weight0, out0); out0 = mad(in0.y, weight1, out0); @@ -617,12 +600,7 @@ void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS } } } - - out0 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out0) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC4); - out1 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out1) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC4); - out2 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out2) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum2) * dequantOffsetC4); - out3 = vbias + CONVERT_COMPUTE_FLOAT4(convert_float4(out3) * dequantScaleC4 + convert_float4((COMPUTE_FLOAT4)sum3) * dequantOffsetC4); - + #ifdef RELU out0 = fmax(out0, (COMPUTE_FLOAT4)0); out1 = fmax(out1, (COMPUTE_FLOAT4)0); @@ -671,8 +649,7 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS #else __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT *output, __private const int2 in_hw, @@ -685,7 +662,8 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS __private const int2 dilate_hw, __private const int out_w_blocks, __private const int out_c_blocks, - __private const int out_h_blocks) { + __private const int out_h_blocks, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -696,25 +674,16 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS const int out_b_idx = out_b_h_idx / out_h_blocks;//equal to in_b_idx const int out_h_idx = (out_b_h_idx % out_h_blocks) << 2; - const float4 dequantScaleC03 = vload4(out_c_idx, dequantScale); - const float4 dequantOffsetC03 = vload4(out_c_idx, dequantOffset); - const float4 dequantScaleC47 = vload4(out_c_idx + 1, dequantScale); - const float4 dequantOffsetC47 = vload4(out_c_idx + 1, dequantOffset); - - COMPUTE_FLOAT4 vbias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT4 out0 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out1 = out0; - COMPUTE_FLOAT4 out2 = out0; - COMPUTE_FLOAT4 out3 = out0; - COMPUTE_FLOAT4 vbias1 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx + 1, bias)); - COMPUTE_FLOAT4 out4 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out5 = out0; - COMPUTE_FLOAT4 out6 = out0; - COMPUTE_FLOAT4 out7 = out0; - COMPUTE_FLOAT sum0 = 0; - COMPUTE_FLOAT sum1 = 0; - COMPUTE_FLOAT sum2 = 0; - COMPUTE_FLOAT sum3 = 0; + COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); + COMPUTE_FLOAT4 out0 = bias0; + COMPUTE_FLOAT4 out1 = bias0; + COMPUTE_FLOAT4 out2 = bias0; + COMPUTE_FLOAT4 out3 = bias0; + COMPUTE_FLOAT4 bias1 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx + 1, bias)); + COMPUTE_FLOAT4 out4 = bias1; + COMPUTE_FLOAT4 out5 = bias1; + COMPUTE_FLOAT4 out6 = bias1; + COMPUTE_FLOAT4 out7 = bias1; const int in_w_idx_base = mad24(out_w_idx, stride_hw.y, -pad_hw.y); @@ -731,6 +700,13 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS const int weight_ic_offset = out_c_blocks * weight_oc_offset; const int in_hw_size = in_hw.x * in_hw.y; for(ushort in_c_idx = 0; in_c_idx < in_c_blocks; in_c_idx++) { + int kindex = (in_c_idx * 4) / blockDim * out_c_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT8 ScaleOffset1 = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx + 1, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); + COMPUTE_FLOAT4 scale1 = (COMPUTE_FLOAT4)(ScaleOffset1.s0, ScaleOffset1.s2, ScaleOffset1.s4, ScaleOffset1.s6); + COMPUTE_FLOAT4 offset1 = (COMPUTE_FLOAT4)(ScaleOffset1.s1, ScaleOffset1.s3, ScaleOffset1.s5, ScaleOffset1.s7); //weights NC4HW4 [1, 4*icC4, ocC4*kh*kw, 1] xic4 //index: [0, 4*in_c_idx, out_c_idx*kh*kw + kh_start*kw + kw_start, 0] const int inp_offset_base = (out_b_idx * in_c_blocks + in_c_idx) * in_hw.x * in_hw.y * 4; @@ -753,10 +729,10 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS char4 charWeight1 = vload4(0, weight+weight_offset+weight_ic_offset); char4 charWeight2 = vload4(0, weight+weight_offset+weight_ic_offset*2); char4 charWeight3 = vload4(0, weight+weight_offset+weight_ic_offset*3); - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale0 + offset0; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale0 + offset0; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale0 + offset0; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale0 + offset0; #else uchar2 charWeightInt40 = vload2(0, weight+weight_offset/2); uchar2 charWeightInt41 = vload2(0, weight+weight_offset/2+weight_ic_offset/2); @@ -782,16 +758,12 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale0 + offset0; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale0 + offset0; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale0 + offset0; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale0 + offset0; #endif - - sum0 += (in0.x + in0.y + in0.z + in0.w); - sum1 += (in1.x + in1.y + in1.z + in1.w); - sum2 += (in2.x + in2.y + in2.z + in2.w); - sum3 += (in3.x + in3.y + in3.z + in3.w); + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out0 = mad(in0.x, weight0, out0); out0 = mad(in0.y, weight1, out0); @@ -818,10 +790,10 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS charWeight1 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset); charWeight2 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset*2); charWeight3 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset*3); - weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale1 + offset1; + weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale1 + offset1; + weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale1 + offset1; + weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale1 + offset1; #else charWeightInt40 = vload2(0, weight+weight_offset/2+weight_oc_offset/2); charWeightInt41 = vload2(0, weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2); @@ -847,11 +819,12 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale1 + offset1; + weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale1 + offset1; + weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale1 + offset1; + weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale1 + offset1; #endif + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out4 = mad(in0.x, weight0, out4); out4 = mad(in0.y, weight1, out4); @@ -878,15 +851,6 @@ void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS } } - out0 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out0) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC03); - out1 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out1) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC03); - out2 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out2) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum2) * dequantOffsetC03); - out3 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out3) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum3) * dequantOffsetC03); - out4 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out4) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC47); - out5 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out5) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC47); - out6 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out6) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum2) * dequantOffsetC47); - out7 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out7) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum3) * dequantOffsetC47); - #ifdef RELU out0 = fmax(out0, (COMPUTE_FLOAT4)0); out1 = fmax(out1, (COMPUTE_FLOAT4)0); @@ -974,8 +938,7 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS #else __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT *output, __private const int2 in_hw, @@ -988,7 +951,8 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS __private const int2 dilate_hw, __private const int out_w_blocks, __private const int out_c_blocks, - __private const int out_h_blocks) { + __private const int out_h_blocks, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -998,20 +962,13 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS const int out_w_idx = out_c_w_idx % out_w_blocks; const int out_b_idx = out_b_h_idx / out_h_blocks;//equal to in_b_idx const int out_h_idx = (out_b_h_idx % out_h_blocks) << 1; - - const float4 dequantScaleC03 = vload4(out_c_idx, dequantScale); - const float4 dequantOffsetC03 = vload4(out_c_idx, dequantOffset); - const float4 dequantScaleC47 = vload4(out_c_idx + 1, dequantScale); - const float4 dequantOffsetC47 = vload4(out_c_idx + 1, dequantOffset); - - COMPUTE_FLOAT4 vbias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT4 out0 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out1 = out0; - COMPUTE_FLOAT4 vbias1 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx + 1, bias)); - COMPUTE_FLOAT4 out2 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out3 = out0; - COMPUTE_FLOAT sum0 = 0; - COMPUTE_FLOAT sum1 = 0; + + COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); + COMPUTE_FLOAT4 out0 = bias0; + COMPUTE_FLOAT4 out1 = bias0; + COMPUTE_FLOAT4 bias1 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx + 1, bias)); + COMPUTE_FLOAT4 out2 = bias1; + COMPUTE_FLOAT4 out3 = bias1; const int in_w_idx_base = mad24(out_w_idx, stride_hw.y, -pad_hw.y); @@ -1027,6 +984,13 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS const int in_hw_size = in_hw.x * in_hw.y; // weight: [ic/4, oc, 4], loop: ic/4 for(ushort in_c_idx = 0; in_c_idx < in_c_blocks; in_c_idx++) { + int kindex = (in_c_idx * 4) / blockDim * out_c_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT8 ScaleOffset1 = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx + 1, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); + COMPUTE_FLOAT4 scale1 = (COMPUTE_FLOAT4)(ScaleOffset1.s0, ScaleOffset1.s2, ScaleOffset1.s4, ScaleOffset1.s6); + COMPUTE_FLOAT4 offset1 = (COMPUTE_FLOAT4)(ScaleOffset1.s1, ScaleOffset1.s3, ScaleOffset1.s5, ScaleOffset1.s7); //weights NC4HW4 [1, 4*icC4, ocC4*kh*kw, 1] xic4 //index: [0, 4*in_c_idx, out_c_idx*kh*kw + kh_start*kw + kw_start, 0] const int inp_offset_base = (out_b_idx * in_c_blocks + in_c_idx) * in_hw.x * in_hw.y * 4; @@ -1044,10 +1008,10 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS char4 charWeight1 = vload4(0, weight+weight_offset+weight_ic_offset); char4 charWeight2 = vload4(0, weight+weight_offset+weight_ic_offset*2); char4 charWeight3 = vload4(0, weight+weight_offset+weight_ic_offset*3); - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale0 + offset0; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale0 + offset0; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale0 + offset0; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale0 + offset0; #else uchar2 charWeightInt40 = vload2(0, weight+weight_offset/2); uchar2 charWeightInt41 = vload2(0, weight+weight_offset/2+weight_ic_offset/2); @@ -1073,15 +1037,12 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale0 + offset0; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale0 + offset0; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale0 + offset0; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale0 + offset0; #endif - - sum0 += (in0.x + in0.y + in0.z + in0.w); - sum1 += (in1.x + in1.y + in1.z + in1.w); - + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out0 = mad(in0.x, weight0, out0); out0 = mad(in0.y, weight1, out0); out0 = mad(in0.z, weight2, out0); @@ -1097,10 +1058,10 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS charWeight1 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset); charWeight2 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset*2); charWeight3 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset*3); - weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale1 + offset1; + weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale1 + offset1; + weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale1 + offset1; + weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale1 + offset1; #else charWeightInt40 = vload2(0, weight+weight_offset/2+weight_oc_offset/2); charWeightInt41 = vload2(0, weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2); @@ -1126,11 +1087,12 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0& MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1& MOD_NUM) - 8; - weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); -#endif + weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale1 + offset1; + weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale1 + offset1; + weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale1 + offset1; + weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale1 + offset1; +#endif + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out2 = mad(in0.x, weight0, out2); out2 = mad(in0.y, weight1, out2); out2 = mad(in0.z, weight2, out2); @@ -1146,11 +1108,6 @@ void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS } } - out0 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out0) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC03); - out1 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out1) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC03); - out2 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out2) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC47); - out3 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out3) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC47); - #ifdef RELU out0 = fmax(out0, (COMPUTE_FLOAT4)0); out1 = fmax(out1, (COMPUTE_FLOAT4)0); @@ -1208,8 +1165,7 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS #else __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT *output, __private const int2 in_hw, @@ -1222,7 +1178,8 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS __private const int2 dilate_hw, __private const int out_w_blocks, __private const int out_c_blocks, - __private const int out_h_blocks) { + __private const int out_h_blocks, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -1233,25 +1190,16 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS const int out_b_idx = out_b_h_idx / out_hw.x;//equal to in_b_idx const int out_h_idx = out_b_h_idx % out_hw.x; - const float4 dequantScaleC03 = vload4(out_c_idx, dequantScale); - const float4 dequantOffsetC03 = vload4(out_c_idx, dequantOffset); - const float4 dequantScaleC47 = vload4(out_c_idx + 1, dequantScale); - const float4 dequantOffsetC47 = vload4(out_c_idx + 1, dequantOffset); - - COMPUTE_FLOAT4 vbias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT4 out0 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out1 = out0; - COMPUTE_FLOAT4 out2 = out0; - COMPUTE_FLOAT4 out3 = out0; - COMPUTE_FLOAT4 vbias1 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx + 1, bias)); - COMPUTE_FLOAT4 out4 = (COMPUTE_FLOAT4)0; - COMPUTE_FLOAT4 out5 = out0; - COMPUTE_FLOAT4 out6 = out0; - COMPUTE_FLOAT4 out7 = out0; - COMPUTE_FLOAT sum0 = 0; - COMPUTE_FLOAT sum1 = 0; - COMPUTE_FLOAT sum2 = 0; - COMPUTE_FLOAT sum3 = 0; + COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); + COMPUTE_FLOAT4 out0 = bias0; + COMPUTE_FLOAT4 out1 = bias0; + COMPUTE_FLOAT4 out2 = bias0; + COMPUTE_FLOAT4 out3 = bias0; + COMPUTE_FLOAT4 bias1 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx + 1, bias)); + COMPUTE_FLOAT4 out4 = bias1; + COMPUTE_FLOAT4 out5 = bias1; + COMPUTE_FLOAT4 out6 = bias1; + COMPUTE_FLOAT4 out7 = bias1; const int in_w0_idx_base = mad24(out_w_idx, stride_hw.y, -pad_hw.y); const int in_w1_idx_base = in_w0_idx_base + stride_hw.y; @@ -1267,6 +1215,13 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS const int weight_oc_offset = filter_hw.x * filter_hw.y * 4; const int weight_ic_offset = out_c_blocks * weight_oc_offset; for(ushort in_c_idx = 0; in_c_idx < in_c_blocks; in_c_idx++) { + int kindex = (in_c_idx * 4) / blockDim * out_c_blocks * 8; + COMPUTE_FLOAT8 ScaleOffset0 = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + COMPUTE_FLOAT8 ScaleOffset1 = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx + 1, dequantScaleOffset + kindex)); + COMPUTE_FLOAT4 scale0 = (COMPUTE_FLOAT4)(ScaleOffset0.s0, ScaleOffset0.s2, ScaleOffset0.s4, ScaleOffset0.s6); + COMPUTE_FLOAT4 offset0 = (COMPUTE_FLOAT4)(ScaleOffset0.s1, ScaleOffset0.s3, ScaleOffset0.s5, ScaleOffset0.s7); + COMPUTE_FLOAT4 scale1 = (COMPUTE_FLOAT4)(ScaleOffset1.s0, ScaleOffset1.s2, ScaleOffset1.s4, ScaleOffset1.s6); + COMPUTE_FLOAT4 offset1 = (COMPUTE_FLOAT4)(ScaleOffset1.s1, ScaleOffset1.s3, ScaleOffset1.s5, ScaleOffset1.s7); //weights NC4HW4 [1, 4*icC4, ocC4*kh*kw, 1] xic4 //index: [0, 4*in_c_idx, out_c_idx*kh*kw + kh_start*kw + kw_start, 0] int weight_offset = ((((4*in_c_idx+0)* out_c_blocks + out_c_idx) *filter_hw.x + kh_start)*filter_hw.y + 0) * 4; @@ -1290,10 +1245,10 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS char4 charWeight1 = vload4(0, weight+weight_offset+weight_ic_offset); char4 charWeight2 = vload4(0, weight+weight_offset+weight_ic_offset*2); char4 charWeight3 = vload4(0, weight+weight_offset+weight_ic_offset*3); - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale0 + offset0; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale0 + offset0; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale0 + offset0; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale0 + offset0; #else uchar2 charWeightInt40 = vload2(0, weight+weight_offset/2); uchar2 charWeightInt41 = vload2(0, weight+weight_offset/2+weight_ic_offset/2); @@ -1319,16 +1274,12 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + COMPUTE_FLOAT4 weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale0 + offset0; + COMPUTE_FLOAT4 weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale0 + offset0; + COMPUTE_FLOAT4 weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale0 + offset0; + COMPUTE_FLOAT4 weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale0 + offset0; #endif - - sum0 += (in0.x + in0.y + in0.z + in0.w); - sum1 += (in1.x + in1.y + in1.z + in1.w); - sum2 += (in2.x + in2.y + in2.z + in2.w); - sum3 += (in3.x + in3.y + in3.z + in3.w); + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out0 = mad(in0.x, weight0, out0); out0 = mad(in0.y, weight1, out0); @@ -1355,10 +1306,10 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS charWeight1 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset); charWeight2 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset*2); charWeight3 = vload4(0, weight+weight_offset+weight_oc_offset+weight_ic_offset*3); - weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale1 + offset1; + weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale1 + offset1; + weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale1 + offset1; + weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale1 + offset1; #else charWeightInt40 = vload2(0, weight+weight_offset/2+weight_oc_offset/2); charWeightInt41 = vload2(0, weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2); @@ -1384,11 +1335,12 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS charWeight3.y = (charWeightInt43.s0 & MOD_NUM) - 8; charWeight3.z = (charWeightInt43.s1 >> 4) - 8; charWeight3.w = (charWeightInt43.s1 & MOD_NUM) - 8; - weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0); - weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1); - weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2); - weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3); + weight0 = CONVERT_COMPUTE_FLOAT4(charWeight0) * scale1 + offset1; + weight1 = CONVERT_COMPUTE_FLOAT4(charWeight1) * scale1 + offset1; + weight2 = CONVERT_COMPUTE_FLOAT4(charWeight2) * scale1 + offset1; + weight3 = CONVERT_COMPUTE_FLOAT4(charWeight3) * scale1 + offset1; #endif + PADZEROSVEC(in_c_idx, inChannel, weight0, weight1, weight2, weight3); out4 = mad(in0.x, weight0, out4); out4 = mad(in0.y, weight1, out4); @@ -1415,15 +1367,6 @@ void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS } } - out0 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out0) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC03); - out1 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out1) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC03); - out2 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out2) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum2) * dequantOffsetC03); - out3 = vbias0 + CONVERT_COMPUTE_FLOAT4(convert_float4(out3) * dequantScaleC03 + convert_float4((COMPUTE_FLOAT4)sum3) * dequantOffsetC03); - out4 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out4) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum0) * dequantOffsetC47); - out5 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out5) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum1) * dequantOffsetC47); - out6 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out6) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum2) * dequantOffsetC47); - out7 = vbias1 + CONVERT_COMPUTE_FLOAT4(convert_float4(out7) * dequantScaleC47 + convert_float4((COMPUTE_FLOAT4)sum3) * dequantOffsetC47); - #ifdef RELU out0 = fmax(out0, (COMPUTE_FLOAT4)0); out1 = fmax(out1, (COMPUTE_FLOAT4)0); diff --git a/source/backend/opencl/execution/cl/gemm.cl b/source/backend/opencl/execution/cl/gemm.cl index a3ec5d516..eb2d9e19f 100644 --- a/source/backend/opencl/execution/cl/gemm.cl +++ b/source/backend/opencl/execution/cl/gemm.cl @@ -277,16 +277,24 @@ __kernel void gemmWinogradW2(__read_only image2d_t uInput, __read_only image2d_t } } +#ifdef INPUT_CHANNEL_LEAVE + #define PADZEROSVEC(k, channel, data0, data1, data2, data3) \ + data0 = (k << 2) < channel ? data0 : 0; \ + data1 = (k << 2) + 1 < channel ? data1 : 0; \ + data2 = (k << 2) + 2 < channel ? data2 : 0; \ + data3 = (k << 2) + 3 < channel ? data3 : 0; +#else + #define PADZEROSVEC(k, channel, data0, data1, data2, data3) +#endif + __kernel void gemm_conv(GLOBAL_SIZE_DIM2 __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) __global const char *weight, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *weight, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #else __global const FLOAT *weight, #endif @@ -294,13 +302,16 @@ __kernel void gemm_conv(GLOBAL_SIZE_DIM2 __write_only image2d_t output, __private const int dstChannelC4, __private const int srcChannelC4, - __private const int batch) { + __private const int batch +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + ,__private const int blockDim + ,__private const int srcChannel +#endif +) { int2 pos = (int2)(get_global_id(0), get_global_id(1)); //cout/4, b UNIFORM_BOUNDRY_CHECK(pos.x, pos.y); - FLOAT4 bias0 = RI_F(bias, SAMPLER, (int2)(pos.x, 0)); - FLOAT sum = 0; - FLOAT4 out = 0; + FLOAT4 out = RI_F(bias, SAMPLER, (int2)(pos.x, 0)); #if (defined USE_LOW_BIT_WEIGHT_INT8) int weight_offset = pos.x * 16; @@ -312,17 +323,23 @@ __kernel void gemm_conv(GLOBAL_SIZE_DIM2 int weight_offset = pos.x * 16; int weight_oc_offset = dstChannelC4 * 16; #endif - -#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) - const FLOAT4 Scale = vload4(pos.x, dequantScale); - const FLOAT4 Offset = vload4(pos.x, dequantOffset); -#endif for (int k = 0; k < srcChannelC4; ++k) { +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + int kindex = (k * 4) / blockDim * dstChannelC4 * 8; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(pos.x, dequantScaleOffset + kindex)); + COMPUTE_FLOAT16 scale = (COMPUTE_FLOAT16)(ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6, + ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6, + ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6, + ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6); + COMPUTE_FLOAT16 offset = (COMPUTE_FLOAT16)(ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7, + ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7, + ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7, + ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7); +#endif FLOAT4 in = RI_F(input, SAMPLER, (int2)(k, pos.y)); #if (defined USE_LOW_BIT_WEIGHT_INT8) - FLOAT16 weights = CONVERT_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); - sum += in.x + in.y + in.z + in.w; + FLOAT16 weights = CONVERT_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * scale + offset; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); char16 charWeights = 0; @@ -342,12 +359,12 @@ __kernel void gemm_conv(GLOBAL_SIZE_DIM2 charWeights.sd = (charWeightsInt4.s6 & 15) - 8; charWeights.se = (charWeightsInt4.s7 >> 4) - 8; charWeights.sf = (charWeightsInt4.s7 & 15) - 8; - FLOAT16 weights = CONVERT_FLOAT16(charWeights); - sum += in.x + in.y + in.z + in.w; + FLOAT16 weights = CONVERT_FLOAT16(charWeights) * scale + offset; #else FLOAT16 weights = vload16(0, weight + weight_offset + k * weight_oc_offset); #endif + PADZEROSVEC(k, srcChannel, weights.s0123, weights.s4567, weights.s89ab, weights.scdef); out = mad((FLOAT4)in.x, (FLOAT4)weights.s0123, out); out = mad((FLOAT4)in.y, (FLOAT4)weights.s4567, out); @@ -355,9 +372,6 @@ __kernel void gemm_conv(GLOBAL_SIZE_DIM2 out = mad((FLOAT4)in.w, (FLOAT4)weights.scdef, out); } -#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) - out = bias0 + mad(out, Scale, sum * Offset); -#endif #ifdef RELU out = fmax(out, (FLOAT4)0); #endif @@ -373,12 +387,10 @@ __kernel void gemm_conv_b2(GLOBAL_SIZE_DIM2 __read_only image2d_t input, #if (defined USE_LOW_BIT_WEIGHT_INT8) __global const char *weight, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *weight, - __global const FLOAT *dequantScale, - __global const FLOAT *dequantOffset, + __global const float *dequantScaleOffset, #else __global const FLOAT *weight, #endif @@ -386,15 +398,19 @@ __kernel void gemm_conv_b2(GLOBAL_SIZE_DIM2 __write_only image2d_t output, __private const int dstChannelC4, __private const int srcChannelC4, - __private const int batch) { + __private const int batch +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + ,__private const int blockDim + ,__private const int srcChannel +#endif +) { int2 pos = (int2)(get_global_id(0), get_global_id(1)); //cout/4, b UNIFORM_BOUNDRY_CHECK(pos.x, pos.y); int pos_x = pos.x << 2; int pos_y = pos.y << 1; FLOAT4 bias0 = RI_F(bias, SAMPLER, (int2)(pos.x, 0)); - FLOAT sum0 = 0, sum1 = 0; - FLOAT4 out0 = (FLOAT4)0, out1 = (FLOAT4)0; + FLOAT4 out0 = bias0, out1 = bias0; #if (defined USE_LOW_BIT_WEIGHT_INT8) int weight_offset = pos.x * 16; @@ -406,19 +422,24 @@ __kernel void gemm_conv_b2(GLOBAL_SIZE_DIM2 int weight_offset = pos.x * 16; int weight_oc_offset = dstChannelC4 * 16; #endif - -#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) - const FLOAT4 Scale = vload4(pos.x, dequantScale); - const FLOAT4 Offset = vload4(pos.x, dequantOffset); -#endif for (int k = 0; k < srcChannelC4; ++k) { +#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) + int kindex = (k * 4) / blockDim * dstChannelC4 * 8; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(pos.x, dequantScaleOffset + kindex)); + COMPUTE_FLOAT16 scale = (COMPUTE_FLOAT16)(ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6, + ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6, + ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6, + ScaleOffset.s0, ScaleOffset.s2, ScaleOffset.s4, ScaleOffset.s6); + COMPUTE_FLOAT16 offset = (COMPUTE_FLOAT16)(ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7, + ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7, + ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7, + ScaleOffset.s1, ScaleOffset.s3, ScaleOffset.s5, ScaleOffset.s7); +#endif FLOAT4 in0 = RI_F(input, SAMPLER, (int2)(k, pos_y)); FLOAT4 in1 = RI_F(input, SAMPLER, (int2)(k, pos_y + 1)); #if (defined USE_LOW_BIT_WEIGHT_INT8) - FLOAT16 weights = CONVERT_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); - sum0 += in0.x + in0.y + in0.z + in0.w; - sum1 += in1.x + in1.y + in1.z + in1.w; + FLOAT16 weights = CONVERT_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * scale + offset; #elif (defined USE_LOW_BIT_WEIGHT_INT4) uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); char16 charWeights = 0; @@ -438,12 +459,11 @@ __kernel void gemm_conv_b2(GLOBAL_SIZE_DIM2 charWeights.sd = (charWeightsInt4.s6 & 15) - 8; charWeights.se = (charWeightsInt4.s7 >> 4) - 8; charWeights.sf = (charWeightsInt4.s7 & 15) - 8; - FLOAT16 weights = CONVERT_FLOAT16(charWeights); - sum0 += in0.x + in0.y + in0.z + in0.w; - sum1 += in1.x + in1.y + in1.z + in1.w; + FLOAT16 weights = CONVERT_FLOAT16(charWeights) * scale + offset; #else FLOAT16 weights = vload16(0, weight + weight_offset + k * weight_oc_offset); #endif + PADZEROSVEC(k, srcChannel, weights.s0123, weights.s4567, weights.s89ab, weights.scdef); out0 = mad((FLOAT4)in0.x, (FLOAT4)weights.s0123, out0); out0 = mad((FLOAT4)in0.y, (FLOAT4)weights.s4567, out0); @@ -455,10 +475,6 @@ __kernel void gemm_conv_b2(GLOBAL_SIZE_DIM2 out1 = mad((FLOAT4)in1.z, (FLOAT4)weights.s89ab, out1); out1 = mad((FLOAT4)in1.w, (FLOAT4)weights.scdef, out1); } -#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) - out0 = bias0 + mad(out0, Scale, sum0 * Offset); - out1 = bias0 + mad(out1, Scale, sum1 * Offset); -#endif #ifdef RELU out0 = fmax(out0, (FLOAT4)0); out1 = fmax(out1, (FLOAT4)0); diff --git a/source/backend/opencl/execution/cl/gemm_quant_batch_buf.cl b/source/backend/opencl/execution/cl/gemm_quant_batch_buf.cl new file mode 100644 index 000000000..3fc8fd050 --- /dev/null +++ b/source/backend/opencl/execution/cl/gemm_quant_batch_buf.cl @@ -0,0 +1,780 @@ +#ifdef MNN_SUPPORT_FP16 +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +#endif + +#define GLOBAL_SIZE_DIM2 \ + __private int global_size_dim0, __private int global_size_dim1, + +#define UNIFORM_BOUNDRY_CHECK(index0, index1) \ + if(index0 >= global_size_dim0 || index1 >= global_size_dim1) { \ + return; \ + } + +#define GLOBAL_SIZE_DIM3 \ + __private int global_size_dim0, __private int global_size_dim1, __private int global_size_dim2, + +#define UNIFORM_BOUNDRY_CHECK3(index0, index1, index2) \ + if(index0 >= global_size_dim0 || index1 >= global_size_dim1 || index2 >= global_size_dim2) { \ + return; \ + } + +#define UCHAR16_TO_2CHAR16(a, b, c) \ + a.s0 = (c.s0 >> 4) - 8; a.s1 = (c.s0 & 15) - 8; a.s2 = (c.s1 >> 4) - 8; a.s3 = (c.s1 & 15) - 8; a.s4 = (c.s2 >> 4) - 8; a.s5 = (c.s2 & 15) - 8; a.s6 = (c.s3 >> 4) - 8; a.s7 = (c.s3 & 15) - 8; \ + a.s8 = (c.s4 >> 4) - 8; a.s9 = (c.s4 & 15) - 8; a.sa = (c.s5 >> 4) - 8; a.sb = (c.s5 & 15) - 8; a.sc = (c.s6 >> 4) - 8; a.sd = (c.s6 & 15) - 8; a.se = (c.s7 >> 4) - 8; a.sf = (c.s7 & 15) - 8; \ + b.s0 = (c.s8 >> 4) - 8; b.s1 = (c.s8 & 15) - 8; b.s2 = (c.s9 >> 4) - 8; b.s3 = (c.s9 & 15) - 8; b.s4 = (c.sa >> 4) - 8; b.s5 = (c.sa & 15) - 8; b.s6 = (c.sb >> 4) - 8; b.s7 = (c.sb & 15) - 8; \ + b.s8 = (c.sc >> 4) - 8; b.s9 = (c.sc & 15) - 8; b.sa = (c.sd >> 4) - 8; b.sb = (c.sd & 15) - 8; b.sc = (c.se >> 4) - 8; b.sd = (c.se & 15) - 8; b.se = (c.sf >> 4) - 8; b.sf = (c.sf & 15) - 8; + +#define UCHAR8_TO_CHAR16(a, c) \ + a.s0 = (c.s0 >> 4) - 8; a.s1 = (c.s0 & 15) - 8; a.s2 = (c.s1 >> 4) - 8; a.s3 = (c.s1 & 15) - 8; a.s4 = (c.s2 >> 4) - 8; a.s5 = (c.s2 & 15) - 8; a.s6 = (c.s3 >> 4) - 8; a.s7 = (c.s3 & 15) - 8; \ + a.s8 = (c.s4 >> 4) - 8; a.s9 = (c.s4 & 15) - 8; a.sa = (c.s5 >> 4) - 8; a.sb = (c.s5 & 15) - 8; a.sc = (c.s6 >> 4) - 8; a.sd = (c.s6 & 15) - 8; a.se = (c.s7 >> 4) - 8; a.sf = (c.s7 & 15) - 8; + +#define DOT16X16(a, b, c) \ + c += dot(a.s0123, b.s0123); \ + c += dot(a.s4567, b.s4567); \ + c += dot(a.s89ab, b.s89ab); \ + c += dot(a.scdef, b.scdef); + +__constant sampler_t SAMPLER = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; + +__kernel void reshape_nchw4_nhwc4(GLOBAL_SIZE_DIM3 +__global const FLOAT* input, +__global FLOAT* output, +__private const int width_height, +__private const int batch, +__private const int channel, +__private const int channelC4){ + const int x = get_global_id(0); //c + const int y = get_global_id(1); //b + const int wh = get_global_id(2); // w*h + + UNIFORM_BOUNDRY_CHECK3(x, y, wh); + + const int x4 = x << 2; + const int y4 = y << 2; + const int channel4 = channelC4 * 4; + const int stride = channel4 * width_height; + const int input_offset = (y4 * channel4 + x4) * width_height + wh * 4; + const int output_offset = ((y * width_height + wh) * channel4 + x4) * 4; + FLOAT4 in0 = vload4(0, input + input_offset); + FLOAT4 in1 = (y4 + 1 < batch) ? vload4(0, input + input_offset + stride) : (FLOAT4)0; + FLOAT4 in2 = (y4 + 2 < batch) ? vload4(0, input + input_offset + 2 * stride) : (FLOAT4)0; + FLOAT4 in3 = (y4 + 3 < batch) ? vload4(0, input + input_offset + 3 * stride) : (FLOAT4)0; + +#ifdef INPUT_CHANNEL_LEAVE + if(x4 + 3 >= channel){ + FLOAT *in0_ptr = (FLOAT*)&in0; + FLOAT *in1_ptr = (FLOAT*)&in1; + FLOAT *in2_ptr = (FLOAT*)&in2; + FLOAT *in3_ptr = (FLOAT*)&in3; + int remain = x4 + 3 - channel; + for(int i = remain; i >= 0; i--){ + in0_ptr[3 - remain] = 0; + in1_ptr[3 - remain] = 0; + in2_ptr[3 - remain] = 0; + in3_ptr[3 - remain] = 0; + } + } +#endif + + FLOAT16 out = (FLOAT16)(in0.s0, in1.s0, in2.s0, in3.s0, in0.s1, in1.s1, in2.s1, in3.s1, in0.s2, in1.s2, in2.s2, in3.s2, in0.s3, in1.s3, in2.s3, in3.s3); + + vstore16(out, 0, output+output_offset); +} + +__kernel void reshape_nhwc4_nchw4(GLOBAL_SIZE_DIM3 +__global const FLOAT* input, +__global FLOAT* output, +__private const int width_height, +__private const int batch, +__private const int channelC4){ + const int x = get_global_id(0); //c + const int y = get_global_id(1); //b + const int wh = get_global_id(2); //w*h + + UNIFORM_BOUNDRY_CHECK3(x, y, wh); + + const int x4 = x << 2; + const int y4 = y << 2; + const int channel4 = channelC4 * 4; + const int stride = channel4 * width_height; + const int input_offset = ((y * width_height + wh) * channel4 + x4) * 4; + const int output_offset = (y4 * channel4 + x4) * width_height + wh * 4; + FLOAT16 in = vload16(0, input + input_offset); + + FLOAT4 out0 = (FLOAT4)(in.s0, in.s4, in.s8, in.sc); + FLOAT4 out1 = (FLOAT4)(in.s1, in.s5, in.s9, in.sd); + FLOAT4 out2 = (FLOAT4)(in.s2, in.s6, in.sa, in.se); + FLOAT4 out3 = (FLOAT4)(in.s3, in.s7, in.sb, in.sf); + + vstore4(out0, 0, output+output_offset); + if(y4 + 1 >= batch) return; + vstore4(out1, 0, output+output_offset+stride); + if(y4 + 2 >= batch) return; + vstore4(out2, 0, output+output_offset+2*stride); + if(y4 + 3 >= batch) return; + vstore4(out3, 0, output+output_offset+3*stride); +} + + +__kernel void gemm_b4_c4_buf(GLOBAL_SIZE_DIM2 + __global const FLOAT* input, +#if (defined USE_LOW_BIT_WEIGHT_INT8) + __global const char *weight, +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + __global const uchar *weight, +#endif + __global const float *dequantScaleOffset, + __global const FLOAT *bias, + __global FLOAT* output, + __private const int dstChannelC4, + __private const int srcChannelC4, + __private const int blockNum, + __private const int blockDim) { + const int x = get_global_id(0); //c + const int y = get_global_id(1); //b + + UNIFORM_BOUNDRY_CHECK(x, y); + + const int out_c_idx = x; + const int out_b_idx = y << 2; + + COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); + COMPUTE_FLOAT4 out = (COMPUTE_FLOAT4)bias0.s0; + COMPUTE_FLOAT4 out1 = (COMPUTE_FLOAT4)bias0.s1, out2 = (COMPUTE_FLOAT4)bias0.s2, out3 = (COMPUTE_FLOAT4)bias0.s3; + + int input_offset = out_b_idx * srcChannelC4 * 4; + int out_offset = (out_b_idx * dstChannelC4 + out_c_idx * 4) * 4; + +#if (defined USE_LOW_BIT_WEIGHT_INT4) + int weight_offset = out_c_idx * 4 * 8; + int weight_oc_offset = dstChannelC4 * 32; +#else + int weight_offset = out_c_idx * 4 * 16; + int weight_oc_offset = dstChannelC4 * 64; +#endif + + const int loop = (blockDim + 15) / 16; +#ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + const int remain = blockDim - loop_end*16; +#else + const int loop_end = loop; +#endif + + for (int i = 0; i < blockNum; i++){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + int k16 = k << 4; + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; +#if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; + weights2 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 32)) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 48)) * ScaleOffset.s6 + ScaleOffset.s7; +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar16 charWeightsInt40 = vload16(0, weight + weight_offset + k * weight_oc_offset); + uchar16 charWeightsInt41 = vload16(0, weight + weight_offset + k * weight_oc_offset + 16); + { + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt40); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt41); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s6 + ScaleOffset.s7; + } + } +#endif + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + COMPUTE_FLOAT *weights2_ptr = (COMPUTE_FLOAT *)&weights2; + COMPUTE_FLOAT *weights3_ptr = (COMPUTE_FLOAT *)&weights3; + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights1_ptr[i], out1); + out2 = mad(in, weights2_ptr[i], out2); + out3 = mad(in, weights3_ptr[i], out3); + } + } +#ifdef INPUT_CHANNEL_LEAVE + { + int k = i * loop + loop_end; + int k16 = k << 4; + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; +#if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; + weights2 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 32)) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 48)) * ScaleOffset.s6 + ScaleOffset.s7; +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar16 charWeightsInt40 = vload16(0, weight + weight_offset + k * weight_oc_offset); + uchar16 charWeightsInt41 = vload16(0, weight + weight_offset + k * weight_oc_offset + 16); + { + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt40); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt41); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s6 + ScaleOffset.s7; + } + } +#endif + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + COMPUTE_FLOAT *weights2_ptr = (COMPUTE_FLOAT *)&weights2; + COMPUTE_FLOAT *weights3_ptr = (COMPUTE_FLOAT *)&weights3; + for (int i = 0; i < remain; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights1_ptr[i], out1); + out2 = mad(in, weights2_ptr[i], out2); + out3 = mad(in, weights3_ptr[i], out3); + } + } +#endif + } +#ifdef RELU + out = fmax(out, (COMPUTE_FLOAT4)0); + out1 = fmax(out1, (COMPUTE_FLOAT4)0); + out2 = fmax(out2, (COMPUTE_FLOAT4)0); + out3 = fmax(out3, (COMPUTE_FLOAT4)0); +#endif + +#ifdef RELU6 + out = clamp(out, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); + out1 = clamp(out1, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); + out2 = clamp(out2, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); + out3 = clamp(out3, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); +#endif + + vstore4(CONVERT_FLOAT4(out), 0, output+out_offset); + vstore4(CONVERT_FLOAT4(out1), 0, output+out_offset + 4); + vstore4(CONVERT_FLOAT4(out2), 0, output+out_offset + 8); + vstore4(CONVERT_FLOAT4(out3), 0, output+out_offset + 12); +} + +__kernel void gemm_b4_c2_buf(GLOBAL_SIZE_DIM2 + __global const FLOAT* input, +#if (defined USE_LOW_BIT_WEIGHT_INT8) + __global const char *weight, +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + __global const uchar *weight, +#endif + __global const float *dequantScaleOffset, + __global const FLOAT *bias, + __global FLOAT* output, + __private const int dstChannelC4, + __private const int srcChannelC4, + __private const int blockNum, + __private const int blockDim) { + const int x = get_global_id(0); //c + const int y = get_global_id(1); //b + + UNIFORM_BOUNDRY_CHECK(x, y); + + const int out_c_idx = x; + const int out_b_idx = y << 2; + + COMPUTE_FLOAT2 bias0 = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, bias)); + COMPUTE_FLOAT4 out = (COMPUTE_FLOAT4)bias0.s0; + COMPUTE_FLOAT4 out1 = (COMPUTE_FLOAT4)bias0.s1; + + int input_offset = out_b_idx * srcChannelC4 * 4; + int out_offset = (out_b_idx * dstChannelC4 + out_c_idx * 2) * 4; + +#if (defined USE_LOW_BIT_WEIGHT_INT4) + int weight_offset = out_c_idx * 2 * 8; + int weight_oc_offset = dstChannelC4 * 32; +#else + int weight_offset = out_c_idx * 2 * 16; + int weight_oc_offset = dstChannelC4 * 64; +#endif + + const int loop = (blockDim + 15) / 16; +#ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + const int remain = blockDim - loop_end*16; +#else + const int loop_end = loop; +#endif + + for (int i = 0; i < blockNum; i++){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT4 ScaleOffset = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, dequantScaleOffset + kindex)); + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + int k16 = k << 4; + COMPUTE_FLOAT16 weights0, weights1; +#if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar16 charWeightsInt4 = vload16(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } +#endif + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights1_ptr[i], out1); + } + } +#ifdef INPUT_CHANNEL_LEAVE + { + int k = i * loop + loop_end; + int k16 = k << 4; + + COMPUTE_FLOAT16 weights0, weights1; +#if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar16 charWeightsInt4 = vload16(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } +#endif + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + for (int i = 0; i < remain; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights1_ptr[i], out1); + } + } +#endif + } + +#ifdef RELU + out = fmax(out, (COMPUTE_FLOAT4)0); + out1 = fmax(out1, (COMPUTE_FLOAT4)0); +#endif + +#ifdef RELU6 + out = clamp(out, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); + out1 = clamp(out1, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); +#endif + + vstore4(CONVERT_FLOAT4(out), 0, output+out_offset); + vstore4(CONVERT_FLOAT4(out1), 0, output+out_offset+4); +} + +__kernel void gemm_b4_c1_buf(GLOBAL_SIZE_DIM2 + __global const FLOAT* input, +#if (defined USE_LOW_BIT_WEIGHT_INT8) + __global const char *weight, +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + __global const uchar *weight, +#endif + __global const float *dequantScaleOffset, + __global const FLOAT *bias, + __global FLOAT* output, + __private const int dstChannelC4, + __private const int srcChannelC4, + __private const int blockNum, + __private const int blockDim) { + const int x = get_global_id(0); //c + const int y = get_global_id(1); //b + + UNIFORM_BOUNDRY_CHECK(x, y); + + const int out_c_idx = x; + const int out_b_idx = y << 2; + + COMPUTE_FLOAT bias0 = bias[out_c_idx]; + COMPUTE_FLOAT4 out = (COMPUTE_FLOAT4)bias0; + + int input_offset = out_b_idx * srcChannelC4 * 4; + int out_offset = (out_b_idx * dstChannelC4 + out_c_idx) * 4; + +#if (defined USE_LOW_BIT_WEIGHT_INT4) + int weight_offset = out_c_idx * 8; + int weight_oc_offset = dstChannelC4 * 32; +#else + int weight_offset = out_c_idx * 16; + int weight_oc_offset = dstChannelC4 * 64; +#endif + + const int loop = (blockDim + 15) / 16; +#ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + const int remain = blockDim - loop_end*16; +#else + const int loop_end = loop; +#endif + + for (int i = 0; i < blockNum; i++){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT2 ScaleOffset = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, dequantScaleOffset + kindex)); + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + int k16 = k << 4; + COMPUTE_FLOAT16 weights; +#if (defined USE_LOW_BIT_WEIGHT_INT8) + weights = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights = 0; + UCHAR8_TO_CHAR16(charWeights, charWeightsInt4); + weights = CONVERT_COMPUTE_FLOAT16(charWeights) * ScaleOffset.s0 + ScaleOffset.s1; + } +#endif + COMPUTE_FLOAT *weights_ptr = (COMPUTE_FLOAT *)&weights; + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights_ptr[i], out); + } + } +#ifdef INPUT_CHANNEL_LEAVE + { + int k = i * loop + loop_end; + int k16 = k << 4; + COMPUTE_FLOAT16 weights; +#if (defined USE_LOW_BIT_WEIGHT_INT8) + weights = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights = 0; + UCHAR8_TO_CHAR16(charWeights, charWeightsInt4); + weights = CONVERT_COMPUTE_FLOAT16(charWeights) * ScaleOffset.s0 + ScaleOffset.s1; + } +#endif + COMPUTE_FLOAT *weights_ptr = (COMPUTE_FLOAT *)&weights; + for (int i = 0; i < remain; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights_ptr[i], out); + } + } +#endif + } + +#ifdef RELU + out = fmax(out, (COMPUTE_FLOAT4)0); +#endif + +#ifdef RELU6 + out = clamp(out, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); +#endif + vstore4(CONVERT_FLOAT4(out), 0, output+out_offset); +} +__kernel void gemm_b4_c2_image(GLOBAL_SIZE_DIM2 + __global const FLOAT* input, + __read_only image2d_t weight, + __global const float *dequantScaleOffset, + __global const FLOAT *bias, + __global FLOAT* output, + __private const int dstChannelC4, + __private const int srcChannelC4, + __private const int blockNum, + __private const int blockDim) { + const int x = get_global_id(0); //c + const int y = get_global_id(1); //b + UNIFORM_BOUNDRY_CHECK(x, y); + + const int out_c_idx = x << 1; + const int out_b_idx = y << 2; + + COMPUTE_FLOAT2 bias0 = CONVERT_COMPUTE_FLOAT2(vload2(0, bias + out_c_idx)); + COMPUTE_FLOAT4 out = (COMPUTE_FLOAT4)bias0.s0; + COMPUTE_FLOAT4 out1 = (COMPUTE_FLOAT4)bias0.s1; + + int input_offset = out_b_idx * srcChannelC4 * 4; + int out_offset = (out_b_idx * dstChannelC4 + out_c_idx) * 4; + +#if (defined USE_LOW_BIT_WEIGHT_INT8) + const int loop = (blockDim + 15) / 16; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + const int remain = blockDim - loop_end*16; + #else + const int loop_end = loop; + #endif +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + const int loop = (blockDim + 31) / 32; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + const int remain = blockDim - loop_end*32; + #else + const int loop_end = loop; + #endif +#endif + + for (int i = 0; i < blockNum; i++){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT4 ScaleOffset = CONVERT_COMPUTE_FLOAT4(vload4(0, dequantScaleOffset + out_c_idx * 2 + kindex)); +#if (defined USE_LOW_BIT_WEIGHT_INT8) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + int k16 = k << 4; + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + COMPUTE_FLOAT16 weights1 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k)))) * ScaleOffset.s2 + ScaleOffset.s3; + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights1_ptr[i], out1); + } + } +#ifdef INPUT_CHANNEL_LEAVE + { + int k = i * loop + loop_end; + int k16 = k << 4; + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + COMPUTE_FLOAT16 weights1 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k)))) * ScaleOffset.s2 + ScaleOffset.s3; + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + #pragma unroll + for (int i = 0; i < remain; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights1_ptr[i], out1); + } + } +#endif +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + int k32 = k << 5; + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s2 + ScaleOffset.s3; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + COMPUTE_FLOAT *weights2_ptr = (COMPUTE_FLOAT *)&weights2; + COMPUTE_FLOAT *weights3_ptr = (COMPUTE_FLOAT *)&weights3; + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights2_ptr[i], out1); + } + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i + 16) * 4)); + out = mad(in, weights1_ptr[i], out); + out1 = mad(in, weights3_ptr[i], out1); + } + } +#ifdef INPUT_CHANNEL_LEAVE + { + int k = i * loop + loop_end; + int k32 = k << 5; + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s2 + ScaleOffset.s3; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + COMPUTE_FLOAT *weights2_ptr = (COMPUTE_FLOAT *)&weights2; + COMPUTE_FLOAT *weights3_ptr = (COMPUTE_FLOAT *)&weights3; + for (int i = 0; i < min(16, remain); ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + out1 = mad(in, weights2_ptr[i], out1); + } + for (int i = 16; i < remain; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i) * 4)); + out = mad(in, weights1_ptr[i - 16], out); + out1 = mad(in, weights3_ptr[i - 16], out1); + } + } +#endif +#endif //USE_LOW_BIT_WEIGHT_INT4 + } + +#ifdef RELU + out = fmax(out, (COMPUTE_FLOAT4)0); + out1 = fmax(out1, (COMPUTE_FLOAT4)0); +#endif +#ifdef RELU6 + out = clamp(out, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); + out1 = clamp(out1, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); +#endif + vstore4(CONVERT_FLOAT4(out), 0, output + out_offset); + vstore4(CONVERT_FLOAT4(out1), 0, output + out_offset + 4); +} +__kernel void gemm_b4_c1_image(GLOBAL_SIZE_DIM2 + __global const FLOAT* input, + __read_only image2d_t weight, + __global const float *dequantScaleOffset, + __global const FLOAT *bias, + __global FLOAT* output, + __private const int dstChannelC4, + __private const int srcChannelC4, + __private const int blockNum, + __private const int blockDim) { + const int x = get_global_id(0); //c + const int y = get_global_id(1); //b + UNIFORM_BOUNDRY_CHECK(x, y); + + const int out_c_idx = x; + const int out_b_idx = y << 2; + + COMPUTE_FLOAT bias0 = bias[out_c_idx]; + COMPUTE_FLOAT4 out = (COMPUTE_FLOAT4)bias0; + + int input_offset = out_b_idx * srcChannelC4 * 4; + int out_offset = (out_b_idx * dstChannelC4 + out_c_idx) * 4; + +#if (defined USE_LOW_BIT_WEIGHT_INT8) + const int loop = (blockDim + 15) / 16; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + const int remain = blockDim - loop_end*16; + #else + const int loop_end = loop; + #endif +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + const int loop = (blockDim + 31) / 32; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + const int remain = blockDim - loop_end*32; + #else + const int loop_end = loop; + #endif +#endif + + for (int i = 0; i < blockNum; ++i){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT2 ScaleOffset = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, dequantScaleOffset + kindex)); +#if (defined USE_LOW_BIT_WEIGHT_INT8) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + int k16 = k << 4; + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + } + } +#ifdef INPUT_CHANNEL_LEAVE + { + int k = i * loop + loop_end; + int k16 = k << 4; + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + #pragma unroll + for (int i = 0; i < remain; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k16 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + } + } +#endif +#elif (defined USE_LOW_BIT_WEIGHT_INT4) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + int k32 = k << 5; + COMPUTE_FLOAT16 weights0, weights1; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + } + #pragma unroll + for (int i = 0; i < 16; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i + 16) * 4)); + out = mad(in, weights1_ptr[i], out); + } + } +#ifdef INPUT_CHANNEL_LEAVE + { + int k = i * loop + loop_end; + int k32 = k << 5; + COMPUTE_FLOAT16 weights0, weights1; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + COMPUTE_FLOAT *weights0_ptr = (COMPUTE_FLOAT *)&weights0; + COMPUTE_FLOAT *weights1_ptr = (COMPUTE_FLOAT *)&weights1; + for (int i = 0; i < min(16, remain); ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i) * 4)); + out = mad(in, weights0_ptr[i], out); + } + for (int i = 16; i < remain; ++i){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k32 + i) * 4)); + out = mad(in, weights1_ptr[i - 16], out); + } + } +#endif +#endif //USE_LOW_BIT_WEIGHT_INT4 + } + +#ifdef RELU + out = fmax(out, (COMPUTE_FLOAT4)0); +#endif +#ifdef RELU6 + out = clamp(out, (COMPUTE_FLOAT4)0, (COMPUTE_FLOAT4)6); +#endif + vstore4(CONVERT_FLOAT4(out), 0, output+out_offset); +} + diff --git a/source/backend/opencl/execution/cl/gemv_conv1x1_buf.cl b/source/backend/opencl/execution/cl/gemv_conv1x1_buf.cl index 9c762a8bf..7b4433111 100644 --- a/source/backend/opencl/execution/cl/gemv_conv1x1_buf.cl +++ b/source/backend/opencl/execution/cl/gemv_conv1x1_buf.cl @@ -26,6 +26,18 @@ c += dot(a.s89ab, b.s89ab); \ c += dot(a.scdef, b.scdef); +#ifdef INPUT_CHANNEL_LEAVE + #define PADZEROS(k, channel, data) {\ + COMPUTE_FLOAT* ptr = (COMPUTE_FLOAT*)&data; \ + int remain = k + 15 - channel; \ + for(int r = remain; r >= 0; r--){ \ + ptr[15 - remain] = 0; \ + } \ + } +#else + #define PADZEROS(k, channel, data) +#endif + __constant sampler_t SAMPLER = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 @@ -35,15 +47,17 @@ __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT* output, __private const int dstChannelC4, __private const int srcChannelC4, + __private const int srcChannel, __private const int batch, __private const int height, - __private const int width) { + __private const int width, + __private const int blockNum, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -59,11 +73,9 @@ __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 const int out_h_idx = out_b_h_idx % height; COMPUTE_FLOAT4 bias0 = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, bias)); - COMPUTE_FLOAT sum = 0; - COMPUTE_FLOAT4 out = 0; + COMPUTE_FLOAT4 out = bias0; #ifdef BACTH_BLOCK4 - COMPUTE_FLOAT sum1 = 0, sum2 = 0, sum3 = 0; - COMPUTE_FLOAT4 out1 = 0, out2 = 0, out3 = 0; + COMPUTE_FLOAT4 out1 = bias0, out2 = bias0, out3 = bias0; int input_offset1 = (((out_b_idx + 1) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset2 = (((out_b_idx + 2) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset3 = (((out_b_idx + 3) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; @@ -74,9 +86,7 @@ __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 int input_offset = ((out_b_idx * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int out_offset = (((out_b_idx * dstChannelC4 + out_c_idx) * height + out_h_idx) * width + out_w_idx) * 4; -#ifndef WIDTH_HEIGHT_1 int wh = width * height * 4; -#endif #if (defined USE_LOW_BIT_WEIGHT_INT4) int weight_offset = out_c_idx * 4 * 8; int weight_oc_offset = dstChannelC4 * 32; @@ -84,187 +94,187 @@ __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 int weight_offset = out_c_idx * 4 * 16; int weight_oc_offset = dstChannelC4 * 64; #endif - - const COMPUTE_FLOAT4 Scale = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, dequantScale)); - const COMPUTE_FLOAT4 Offset = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, dequantOffset)); - + + const int loop = (blockDim + 15) / 16; #ifdef INPUT_CHANNEL_LEAVE - const int srcChannelC16 = (srcChannelC4 + 3) >> 2; - for (int k = 0; k < srcChannelC16 - 1; ++k) { + const int loop_end = max(loop - 1, 0); #else - for (int k = 0; k < srcChannelC4/4; ++k) { + const int loop_end = loop; #endif -#ifndef WIDTH_HEIGHT_1 - int k4 = k << 2; -#endif - COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; -#if (defined USE_LOW_BIT_WEIGHT_INT8) - weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); - weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)); - weights2 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 32)); - weights3 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 48)); -#elif (defined USE_LOW_BIT_WEIGHT_INT4) - { - uchar16 charWeightsInt40 = vload16(0, weight + weight_offset + k * weight_oc_offset); - uchar16 charWeightsInt41 = vload16(0, weight + weight_offset + k * weight_oc_offset + 16); + + for (int i = 0; i < blockNum; ++i){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT8 ScaleOffset = CONVERT_COMPUTE_FLOAT8(vload8(out_c_idx, dequantScaleOffset + kindex)); + for (int j = 0; j < loop_end; ++j) { + int k = i * loop + j; + #ifndef WIDTH_HEIGHT_1 + int k4 = k << 2; + #endif + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; + #if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; + weights2 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 32)) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 48)) * ScaleOffset.s6 + ScaleOffset.s7; + #elif (defined USE_LOW_BIT_WEIGHT_INT4) { - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt40); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt41); - weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1); + uchar16 charWeightsInt40 = vload16(0, weight + weight_offset + k * weight_oc_offset); + uchar16 charWeightsInt41 = vload16(0, weight + weight_offset + k * weight_oc_offset + 16); + { + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt40); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt41); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s6 + ScaleOffset.s7; + } } + #endif + { + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out.s0); + DOT16X16(in, weights1, out.s1); + DOT16X16(in, weights2, out.s2); + DOT16X16(in, weights3, out.s3); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset1)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out1.s0); + DOT16X16(in, weights1, out1.s1); + DOT16X16(in, weights2, out1.s2); + DOT16X16(in, weights3, out1.s3); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset2)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out2.s0); + DOT16X16(in, weights1, out2.s1); + DOT16X16(in, weights2, out2.s2); + DOT16X16(in, weights3, out2.s3); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset3)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out3.s0); + DOT16X16(in, weights1, out3.s1); + DOT16X16(in, weights2, out3.s2); + DOT16X16(in, weights3, out3.s3); + } + #endif } -#endif - { - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); -#endif - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out.s0); - DOT16X16(in, weights1, out.s1); - DOT16X16(in, weights2, out.s2); - DOT16X16(in, weights3, out.s3); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset1)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); -#endif - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1.s0); - DOT16X16(in, weights1, out1.s1); - DOT16X16(in, weights2, out1.s2); - DOT16X16(in, weights3, out1.s3); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset2)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); -#endif - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2.s0); - DOT16X16(in, weights1, out2.s1); - DOT16X16(in, weights2, out2.s2); - DOT16X16(in, weights3, out2.s3); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset3)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); -#endif - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3.s0); - DOT16X16(in, weights1, out3.s1); - DOT16X16(in, weights2, out3.s2); - DOT16X16(in, weights3, out3.s3); - } -#endif - } -#ifdef INPUT_CHANNEL_LEAVE - { - int k = srcChannelC16 - 1; - int k4 = k * 4; - COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; -#if (defined USE_LOW_BIT_WEIGHT_INT8) - weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); - weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)); - weights2 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 32)); - weights3 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 48)); -#elif (defined USE_LOW_BIT_WEIGHT_INT4) - { - uchar16 charWeightsInt40 = vload16(0, weight + weight_offset + k * weight_oc_offset); - uchar16 charWeightsInt41 = vload16(0, weight + weight_offset + k * weight_oc_offset + 16); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt40); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt41); - weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1); - } -#endif + #ifdef INPUT_CHANNEL_LEAVE { - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out.s0); - DOT16X16(in, weights1, out.s1); - DOT16X16(in, weights2, out.s2); - DOT16X16(in, weights3, out.s3); - } - -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1.s0); - DOT16X16(in, weights1, out1.s1); - DOT16X16(in, weights2, out1.s2); - DOT16X16(in, weights3, out1.s3); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2.s0); - DOT16X16(in, weights1, out2.s1); - DOT16X16(in, weights2, out2.s2); - DOT16X16(in, weights3, out2.s3); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3.s0); - DOT16X16(in, weights1, out3.s1); - DOT16X16(in, weights2, out3.s2); - DOT16X16(in, weights3, out3.s3); + int k = i * loop + loop_end; + int k4 = k << 2; + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; + #if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; + weights2 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 32)) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 48)) * ScaleOffset.s6 + ScaleOffset.s7; + #elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar16 charWeightsInt40 = vload16(0, weight + weight_offset + k * weight_oc_offset); + uchar16 charWeightsInt41 = vload16(0, weight + weight_offset + k * weight_oc_offset + 16); + { + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt40); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt41); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s4 + ScaleOffset.s5; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s6 + ScaleOffset.s7; + } + } + #endif + PADZEROS(k, srcChannel, weights0); + PADZEROS(k, srcChannel, weights1); + PADZEROS(k, srcChannel, weights2); + PADZEROS(k, srcChannel, weights3); + { + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out.s0); + DOT16X16(in, weights1, out.s1); + DOT16X16(in, weights2, out.s2); + DOT16X16(in, weights3, out.s3); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out1.s0); + DOT16X16(in, weights1, out1.s1); + DOT16X16(in, weights2, out1.s2); + DOT16X16(in, weights3, out1.s3); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out2.s0); + DOT16X16(in, weights1, out2.s1); + DOT16X16(in, weights2, out2.s2); + DOT16X16(in, weights3, out2.s3); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out3.s0); + DOT16X16(in, weights1, out3.s1); + DOT16X16(in, weights2, out3.s2); + DOT16X16(in, weights3, out3.s3); + } + #endif } -#endif + #endif } -#endif - out = bias0 + mad(out, Scale, sum * Offset); #ifdef RELU out = fmax(out, (COMPUTE_FLOAT4)0); #endif @@ -277,7 +287,6 @@ __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 #ifdef BACTH_BLOCK4 if(isValidBatch1){ out_offset += dstChannelC4 * height * width * 4; - out1 = bias0 + mad(out1, Scale, sum1 * Offset); #ifdef RELU out1 = fmax(out1, (COMPUTE_FLOAT4)0); #endif @@ -290,7 +299,6 @@ __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 } if(isValidBatch2){ out_offset += dstChannelC4 * height * width * 4; - out2 = bias0 + mad(out2, Scale, sum2 * Offset); #ifdef RELU out2 = fmax(out2, (COMPUTE_FLOAT4)0); #endif @@ -303,7 +311,6 @@ __kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2 } if(isValidBatch3){ out_offset += dstChannelC4 * height * width * 4; - out3 = bias0 + mad(out3, Scale, sum3 * Offset); #ifdef RELU out3 = fmax(out3, (COMPUTE_FLOAT4)0); #endif @@ -324,15 +331,17 @@ __kernel void gemm_conv_c2_buf(GLOBAL_SIZE_DIM2 #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT* output, __private const int dstChannelC4, __private const int srcChannelC4, + __private const int srcChannel, __private const int batch, __private const int height, - __private const int width) { + __private const int width, + __private const int blockNum, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -348,11 +357,9 @@ __kernel void gemm_conv_c2_buf(GLOBAL_SIZE_DIM2 const int out_h_idx = out_b_h_idx % height; COMPUTE_FLOAT2 bias0 = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, bias)); - COMPUTE_FLOAT sum = 0; - COMPUTE_FLOAT2 out = 0; + COMPUTE_FLOAT2 out = bias0; #ifdef BACTH_BLOCK4 - COMPUTE_FLOAT sum1 = 0, sum2 = 0, sum3 = 0; - COMPUTE_FLOAT2 out1 = 0, out2 = 0, out3 = 0; + COMPUTE_FLOAT2 out1 = bias0, out2 = bias0, out3 = bias0; int input_offset1 = (((out_b_idx + 1) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset2 = (((out_b_idx + 2) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset3 = (((out_b_idx + 3) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; @@ -362,9 +369,7 @@ __kernel void gemm_conv_c2_buf(GLOBAL_SIZE_DIM2 #endif int input_offset = ((out_b_idx * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int out_offset = (((out_b_idx * dstChannelC4 + (out_c_idx * 2) / 4) * height + out_h_idx) * width + out_w_idx) * 4 + ((out_c_idx * 2)%4); -#ifndef WIDTH_HEIGHT_1 int wh = width * height * 4; -#endif #if (defined USE_LOW_BIT_WEIGHT_INT4) int weight_offset = out_c_idx * 2 * 8; int weight_oc_offset = dstChannelC4 * 32; @@ -373,156 +378,152 @@ __kernel void gemm_conv_c2_buf(GLOBAL_SIZE_DIM2 int weight_oc_offset = dstChannelC4 * 64; #endif - const COMPUTE_FLOAT2 Scale = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, dequantScale)); - const COMPUTE_FLOAT2 Offset = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, dequantOffset)); - + const int loop = (blockDim + 15) / 16; #ifdef INPUT_CHANNEL_LEAVE - const int srcChannelC16 = (srcChannelC4 + 3) >> 2; - for (int k = 0; k < srcChannelC16 - 1; ++k) { + const int loop_end = max(loop - 1, 0); #else - for (int k = 0; k < srcChannelC4/4; ++k) { -#endif -#ifndef WIDTH_HEIGHT_1 - int k4 = k << 2; + const int loop_end = loop; #endif - COMPUTE_FLOAT16 weights0, weights1; -#if (defined USE_LOW_BIT_WEIGHT_INT8) - weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); - weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)); -#elif (defined USE_LOW_BIT_WEIGHT_INT4) - { - uchar16 charWeightsInt4 = vload16(0, weight + weight_offset + k * weight_oc_offset); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); - } -#endif - { - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); -#endif - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out.s0); - DOT16X16(in, weights1, out.s1); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset1)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); -#endif - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1.s0); - DOT16X16(in, weights1, out1.s1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset2)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); -#endif - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2.s0); - DOT16X16(in, weights1, out2.s1); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset3)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); -#endif - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3.s0); - DOT16X16(in, weights1, out3.s1); - } -#endif - } -#ifdef INPUT_CHANNEL_LEAVE - { - int k = srcChannelC16 - 1; - int k4 = k * 4; - COMPUTE_FLOAT16 weights0, weights1; -#if (defined USE_LOW_BIT_WEIGHT_INT8) - weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); - weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)); -#elif (defined USE_LOW_BIT_WEIGHT_INT4) - { - uchar16 charWeightsInt4 = vload16(0, weight + weight_offset + k * weight_oc_offset); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); + for (int i = 0; i < blockNum; ++i){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT4 ScaleOffset = CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx, dequantScaleOffset + kindex)); + for (int j = 0; j < loop_end; ++j) { + int k = i * loop + j; + #ifndef WIDTH_HEIGHT_1 + int k4 = k << 2; + #endif + COMPUTE_FLOAT16 weights0, weights1; + #if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; + #elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar16 charWeightsInt4 = vload16(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } + #endif + { + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out.s0); + DOT16X16(in, weights1, out.s1); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset1)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out1.s0); + DOT16X16(in, weights1, out1.s1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset2)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out2.s0); + DOT16X16(in, weights1, out2.s1); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset3)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out3.s0); + DOT16X16(in, weights1, out3.s1); + } + #endif } -#endif + #ifdef INPUT_CHANNEL_LEAVE { - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out.s0); - DOT16X16(in, weights1, out.s1); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1.s0); - DOT16X16(in, weights1, out1.s1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2.s0); - DOT16X16(in, weights1, out2.s1); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3.s0); - DOT16X16(in, weights1, out3.s1); + int k = i * loop + loop_end; + int k4 = k << 2; + COMPUTE_FLOAT16 weights0, weights1; + #if (defined USE_LOW_BIT_WEIGHT_INT8) + weights0 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset + 16)) * ScaleOffset.s2 + ScaleOffset.s3; + #elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar16 charWeightsInt4 = vload16(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } + #endif + PADZEROS(k, srcChannel, weights0); + PADZEROS(k, srcChannel, weights1); + { + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out.s0); + DOT16X16(in, weights1, out.s1); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out1.s0); + DOT16X16(in, weights1, out1.s1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out2.s0); + DOT16X16(in, weights1, out2.s1); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out3.s0); + DOT16X16(in, weights1, out3.s1); + } + #endif } -#endif + #endif } -#endif - out = bias0 + mad(out, Scale, sum * Offset); #ifdef RELU out = fmax(out, (COMPUTE_FLOAT2)0); #endif @@ -535,7 +536,6 @@ __kernel void gemm_conv_c2_buf(GLOBAL_SIZE_DIM2 #ifdef BACTH_BLOCK4 if(isValidBatch1){ out_offset += dstChannelC4 * height * width * 4; - out1 = bias0 + mad(out1, Scale, sum1 * Offset); #ifdef RELU out1 = fmax(out1, (COMPUTE_FLOAT2)0); #endif @@ -548,7 +548,6 @@ __kernel void gemm_conv_c2_buf(GLOBAL_SIZE_DIM2 } if(isValidBatch2){ out_offset += dstChannelC4 * height * width * 4; - out2 = bias0 + mad(out2, Scale, sum2 * Offset); #ifdef RELU out2 = fmax(out2, (COMPUTE_FLOAT2)0); #endif @@ -561,7 +560,6 @@ __kernel void gemm_conv_c2_buf(GLOBAL_SIZE_DIM2 } if(isValidBatch3){ out_offset += dstChannelC4 * height * width * 4; - out3 = bias0 + mad(out3, Scale, sum3 * Offset); #ifdef RELU out3 = fmax(out3, (COMPUTE_FLOAT2)0); #endif @@ -582,15 +580,17 @@ __kernel void gemm_conv_c1_buf(GLOBAL_SIZE_DIM2 #elif (defined USE_LOW_BIT_WEIGHT_INT4) __global const uchar *weight, #endif - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT* output, __private const int dstChannelC4, __private const int srcChannelC4, + __private const int srcChannel, __private const int batch, __private const int height, - __private const int width) { + __private const int width, + __private const int blockNum, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h @@ -606,12 +606,10 @@ __kernel void gemm_conv_c1_buf(GLOBAL_SIZE_DIM2 const int out_h_idx = out_b_h_idx % height; COMPUTE_FLOAT bias0 = bias[out_c_idx]; - COMPUTE_FLOAT sum = 0; - COMPUTE_FLOAT out = 0; + COMPUTE_FLOAT out = bias0; #ifdef BACTH_BLOCK4 - COMPUTE_FLOAT sum1 = 0, sum2 = 0, sum3 = 0; - COMPUTE_FLOAT out1 = 0, out2 = 0, out3 = 0; + COMPUTE_FLOAT out1 = bias0, out2 = bias0, out3 = bias0; int input_offset1 = (((out_b_idx + 1) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset2 = (((out_b_idx + 2) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset3 = (((out_b_idx + 3) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; @@ -622,9 +620,7 @@ __kernel void gemm_conv_c1_buf(GLOBAL_SIZE_DIM2 int input_offset = ((out_b_idx * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int out_offset = (((out_b_idx * dstChannelC4 + out_c_idx/4) * height + out_h_idx) * width + out_w_idx) * 4 + (out_c_idx%4); -#ifndef WIDTH_HEIGHT_1 int wh = width * height * 4; -#endif #if (defined USE_LOW_BIT_WEIGHT_INT4) int weight_offset = out_c_idx * 8; int weight_oc_offset = dstChannelC4 * 32; @@ -632,185 +628,179 @@ __kernel void gemm_conv_c1_buf(GLOBAL_SIZE_DIM2 int weight_offset = out_c_idx * 16; int weight_oc_offset = dstChannelC4 * 64; #endif - - const COMPUTE_FLOAT Scale = dequantScale[out_c_idx]; - const COMPUTE_FLOAT Offset = dequantOffset[out_c_idx]; + + const int loop = (blockDim + 15) / 16; #ifdef INPUT_CHANNEL_LEAVE - const int srcChannelC16 = (srcChannelC4 + 3) >> 2; - for (int k = 0; k < srcChannelC16 - 1; ++k) { -#else - for (int k = 0; k < srcChannelC4/4; ++k) { -#endif -#ifndef WIDTH_HEIGHT_1 - int k4 = k << 2; -#endif - COMPUTE_FLOAT16 weights; -#if (defined USE_LOW_BIT_WEIGHT_INT8) - weights = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); -#elif (defined USE_LOW_BIT_WEIGHT_INT4) - { - uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); - char16 charWeights = 0; - UCHAR8_TO_CHAR16(charWeights, charWeightsInt4); - weights = CONVERT_COMPUTE_FLOAT16(charWeights); - } -#endif - { - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); -#endif - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset1)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); -#endif - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset2)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); -#endif - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out2); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset3)); + const int loop_end = max(loop - 1, 0); #else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); + const int loop_end = loop; #endif - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out3); - } -#endif - } -#ifdef INPUT_CHANNEL_LEAVE - { - int k = srcChannelC16 - 1; - int k4 = k * 4; - COMPUTE_FLOAT16 weights; -#if (defined USE_LOW_BIT_WEIGHT_INT8) - weights = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)); -#elif (defined USE_LOW_BIT_WEIGHT_INT4) - { - uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); - char16 charWeights = 0; - UCHAR8_TO_CHAR16(charWeights, charWeightsInt4); - weights = CONVERT_COMPUTE_FLOAT16(charWeights); + + for (int i = 0; i < blockNum; ++i){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT2 ScaleOffset = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, dequantScaleOffset + kindex)); + for (int j = 0; j < loop_end; ++j) { + int k = i * loop + j; + #ifndef WIDTH_HEIGHT_1 + int k4 = k << 2; + #endif + COMPUTE_FLOAT16 weights; + #if (defined USE_LOW_BIT_WEIGHT_INT8) + weights = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + #elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights = 0; + UCHAR8_TO_CHAR16(charWeights, charWeightsInt4); + weights = CONVERT_COMPUTE_FLOAT16(charWeights) * ScaleOffset.s0 + ScaleOffset.s1; + } + #endif + { + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights, out); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset1)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights, out1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset2)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights, out2); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(k, input + input_offset3)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights, out3); + } + #endif } -#endif + #ifdef INPUT_CHANNEL_LEAVE { - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out2); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights, out3); + int k = i * loop + loop_end; + int k4 = k << 2; + COMPUTE_FLOAT16 weights; + #if (defined USE_LOW_BIT_WEIGHT_INT8) + weights = CONVERT_COMPUTE_FLOAT16(vload16(0, weight + weight_offset + k * weight_oc_offset)) * ScaleOffset.s0 + ScaleOffset.s1; + #elif (defined USE_LOW_BIT_WEIGHT_INT4) + { + uchar8 charWeightsInt4 = vload8(0, weight + weight_offset + k * weight_oc_offset); + char16 charWeights = 0; + UCHAR8_TO_CHAR16(charWeights, charWeightsInt4); + weights = CONVERT_COMPUTE_FLOAT16(charWeights) * ScaleOffset.s0 + ScaleOffset.s1; + } + #endif + PADZEROS(k, srcChannel, weights); + { + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights, out); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights, out1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights, out2); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights, out3); + } + #endif } -#endif + #endif } -#endif - out = bias0 + mad(out, Scale, sum * Offset); #ifdef RELU - out = fmax(out, 0); + out = fmax(out, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out = clamp(out, 0, 6); + out = clamp(out, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out; #ifdef BACTH_BLOCK4 if(isValidBatch1){ out_offset += dstChannelC4 * height * width * 4; - out1 = bias0 + mad(out1, Scale, sum1 * Offset); #ifdef RELU - out1 = fmax(out1, 0); + out1 = fmax(out1, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out1 = clamp(out1, 0, 6); + out1 = clamp(out1, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out1; } if(isValidBatch2){ out_offset += dstChannelC4 * height * width * 4; - out2 = bias0 + mad(out2, Scale, sum2 * Offset); #ifdef RELU - out2 = fmax(out2, 0); + out2 = fmax(out2, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out2 = clamp(out2, 0, 6); + out2 = clamp(out2, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out2; } if(isValidBatch3){ out_offset += dstChannelC4 * height * width * 4; - out3 = bias0 + mad(out3, Scale, sum3 * Offset); #ifdef RELU - out3 = fmax(out3, 0); + out3 = fmax(out3, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out3 = clamp(out3, 0, 6); + out3 = clamp(out3, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out3; @@ -820,15 +810,17 @@ __kernel void gemm_conv_c1_buf(GLOBAL_SIZE_DIM2 __kernel void gemm_conv_c2_image(GLOBAL_SIZE_DIM2 __global const FLOAT* input, __read_only image2d_t weight, - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT* output, __private const int dstChannelC4, __private const int srcChannelC4, + __private const int srcChannel, __private const int batch, __private const int height, - __private const int width) { + __private const int width, + __private const int blockNum, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h UNIFORM_BOUNDRY_CHECK(out_c_w_idx, out_b_h_idx); @@ -843,12 +835,10 @@ __kernel void gemm_conv_c2_image(GLOBAL_SIZE_DIM2 const int out_h_idx = out_b_h_idx % height; COMPUTE_FLOAT2 bias0 = CONVERT_COMPUTE_FLOAT2(vload2(0, bias + out_c_idx)); - COMPUTE_FLOAT2 out = 0; - COMPUTE_FLOAT sum = 0; + COMPUTE_FLOAT2 out = bias0; #ifdef BACTH_BLOCK4 - COMPUTE_FLOAT sum1 = 0, sum2 = 0, sum3 = 0; - COMPUTE_FLOAT2 out1 = 0, out2 = 0, out3 = 0; + COMPUTE_FLOAT2 out1 = bias0, out2 = bias0, out3 = bias0; int input_offset1 = (((out_b_idx + 1) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset2 = (((out_b_idx + 2) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset3 = (((out_b_idx + 3) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; @@ -859,357 +849,349 @@ __kernel void gemm_conv_c2_image(GLOBAL_SIZE_DIM2 int input_offset = ((out_b_idx * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int out_offset = (((out_b_idx * dstChannelC4 + out_c_idx/4) * height + out_h_idx) * width + out_w_idx) * 4 + (out_c_idx % 4); -#ifndef WIDTH_HEIGHT_1 int wh = width * height * 4; -#endif - - const COMPUTE_FLOAT2 Scale = CONVERT_COMPUTE_FLOAT2(vload2(0, dequantScale + out_c_idx)); - const COMPUTE_FLOAT2 Offset = CONVERT_COMPUTE_FLOAT2(vload2(0, dequantOffset + out_c_idx)); #if (defined USE_LOW_BIT_WEIGHT_INT8) -#ifdef INPUT_CHANNEL_LEAVE - const int srcChannelC16 = (srcChannelC4 + 3) >> 2; - for (int k = 0; k < srcChannelC16-1; k++) { -#else - for (int k = 0; k < srcChannelC4/4; k++) { -#endif -#ifndef WIDTH_HEIGHT_1 - int k4 = k * 4; -#endif - COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k)))); - COMPUTE_FLOAT16 weights1 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagef(weight, SAMPLER, (int2)(out_c_idx + 1, k)))); - { - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); -#endif - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out.s0); - DOT16X16(in, weights1, out.s1); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); -#endif - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1.s0); - DOT16X16(in, weights1, out1.s1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); -#endif - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2.s0); - DOT16X16(in, weights1, out2.s1); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); -#endif - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3.s0); - DOT16X16(in, weights1, out3.s1); - } -#endif - } -#ifdef INPUT_CHANNEL_LEAVE - { - int k = srcChannelC16 - 1; - int k4 = k * 4; - COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k)))); - COMPUTE_FLOAT16 weights1 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagef(weight, SAMPLER, (int2)(out_c_idx + 1, k)))); - { - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out.s0); - DOT16X16(in, weights1, out.s1); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1.s0); - DOT16X16(in, weights1, out1.s1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2.s0); - DOT16X16(in, weights1, out2.s1); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3.s0); - DOT16X16(in, weights1, out3.s1); - } -#endif - } -#endif + const int loop = (blockDim + 15) / 16; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + #else + const int loop_end = loop; + #endif #elif (defined USE_LOW_BIT_WEIGHT_INT4) -#ifdef INPUT_CHANNEL_LEAVE - const int srcChannelC32 = (srcChannelC4 + 7) >> 3; - for (int k = 0; k < srcChannelC32-1; k++) { -#else - for (int k = 0; k < srcChannelC4/8; k++) { -#endif -#ifndef WIDTH_HEIGHT_1 - int k8 = k * 8; + const int loop = (blockDim + 31) / 32; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + #else + const int loop_end = loop; + #endif #endif - COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; - { - uchar16 charWeightsInt4 = as_uchar16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k))); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); - } - { - uchar16 charWeightsInt4 = as_uchar16(read_imagef(weight, SAMPLER, (int2)(out_c_idx + 1, k))); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1); + + for (int i = 0; i < blockNum; ++i){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT4 ScaleOffset = CONVERT_COMPUTE_FLOAT4(vload4(0, dequantScaleOffset + out_c_idx * 2 + kindex)); + #if (defined USE_LOW_BIT_WEIGHT_INT8) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + #ifndef WIDTH_HEIGHT_1 + int k4 = k << 2; + #endif + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + COMPUTE_FLOAT16 weights1 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k)))) * ScaleOffset.s2 + ScaleOffset.s3; + { + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out.s0); + DOT16X16(in, weights1, out.s1); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out1.s0); + DOT16X16(in, weights1, out1.s1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out2.s0); + DOT16X16(in, weights1, out2.s1); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out3.s0); + DOT16X16(in, weights1, out3.s1); + } + #endif } + #ifdef INPUT_CHANNEL_LEAVE { - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 3) * wh)); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 7) * wh)); + int k = i * loop + loop_end; + int k4 = k << 2; + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + COMPUTE_FLOAT16 weights1 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k)))) * ScaleOffset.s2 + ScaleOffset.s3; + PADZEROS(k, srcChannel, weights0); + PADZEROS(k, srcChannel, weights1); + { + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out.s0); + DOT16X16(in, weights1, out.s1); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out1.s0); + DOT16X16(in, weights1, out1.s1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out2.s0); + DOT16X16(in, weights1, out2.s1); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out3.s0); + DOT16X16(in, weights1, out3.s1); + } + #endif + } + #endif + #elif (defined USE_LOW_BIT_WEIGHT_INT4) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + #ifndef WIDTH_HEIGHT_1 + int k8 = k << 3; + #endif + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s2 + ScaleOffset.s3; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } + { + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 3) * wh)); -#endif - sum += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out.s0); - DOT16X16(in1, weights1, out.s0); - DOT16X16(in0, weights2, out.s1); - DOT16X16(in1, weights3, out.s1); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 3) * wh)); + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 7) * wh)); + #endif + + DOT16X16(in0, weights0, out.s0); + DOT16X16(in1, weights1, out.s0); + DOT16X16(in0, weights2, out.s1); + DOT16X16(in1, weights3, out.s1); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 3) * wh)); - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 7) * wh)); -#endif - sum1 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum1 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out1.s0); - DOT16X16(in1, weights1, out1.s0); - DOT16X16(in0, weights2, out1.s1); - DOT16X16(in1, weights3, out1.s1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 3) * wh)); + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 7) * wh)); + #endif + DOT16X16(in0, weights0, out1.s0); + DOT16X16(in1, weights1, out1.s0); + DOT16X16(in0, weights2, out1.s1); + DOT16X16(in1, weights3, out1.s1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 3) * wh)); - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 7) * wh)); -#endif - sum2 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum2 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out2.s0); - DOT16X16(in1, weights1, out2.s0); - DOT16X16(in0, weights2, out2.s1); - DOT16X16(in1, weights3, out2.s1); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 3) * wh)); + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 7) * wh)); + #endif + DOT16X16(in0, weights0, out2.s0); + DOT16X16(in1, weights1, out2.s0); + DOT16X16(in0, weights2, out2.s1); + DOT16X16(in1, weights3, out2.s1); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 3) * wh)); - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 7) * wh)); -#endif - sum3 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum3 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out3.s0); - DOT16X16(in1, weights1, out3.s0); - DOT16X16(in0, weights2, out3.s1); - DOT16X16(in1, weights3, out3.s1); - } -#endif - } -#ifdef INPUT_CHANNEL_LEAVE - { - int k = srcChannelC32 - 1; - int k8 = k * 8; - COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; - { - uchar16 charWeightsInt4 = as_uchar16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k))); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); - } - { - uchar16 charWeightsInt4 = as_uchar16(read_imagef(weight, SAMPLER, (int2)(out_c_idx + 1, k))); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1); + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 7) * wh)); + #endif + DOT16X16(in0, weights0, out3.s0); + DOT16X16(in1, weights1, out3.s0); + DOT16X16(in0, weights2, out3.s1); + DOT16X16(in1, weights3, out3.s1); + } + #endif } + #ifdef INPUT_CHANNEL_LEAVE { - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 3) * wh) : (FLOAT4)0); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 7) * wh) : (FLOAT4)0); - sum += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out.s0); - DOT16X16(in1, weights1, out.s0); - DOT16X16(in0, weights2, out.s1); - DOT16X16(in1, weights3, out.s1); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < vload4(0, input + input_offset1 + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < vload4(0, input + input_offset1 + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < vload4(0, input + input_offset1 + (k8 + 3) * wh) : (FLOAT4)0); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 7) * wh) : (FLOAT4)0); - sum1 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum1 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out1.s0); - DOT16X16(in1, weights1, out1.s0); - DOT16X16(in0, weights2, out1.s1); - DOT16X16(in1, weights3, out1.s1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < vload4(0, input + input_offset2 + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < vload4(0, input + input_offset2 + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < vload4(0, input + input_offset2 + (k8 + 3) * wh) : (FLOAT4)0); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 7) * wh) : (FLOAT4)0); - sum2 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum2 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out2.s0); - DOT16X16(in1, weights1, out2.s0); - DOT16X16(in0, weights2, out2.s1); - DOT16X16(in1, weights3, out2.s1); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < vload4(0, input + input_offset3 + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < vload4(0, input + input_offset3 + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < vload4(0, input + input_offset3 + (k8 + 3) * wh) : (FLOAT4)0); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 7) * wh) : (FLOAT4)0); - sum3 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum3 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out3.s0); - DOT16X16(in1, weights1, out3.s0); - DOT16X16(in0, weights2, out3.s1); - DOT16X16(in1, weights3, out3.s1); + int k = i * loop + loop_end; + int k8 = k << 3; + COMPUTE_FLOAT16 weights0, weights1, weights2, weights3; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx + 1, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights2 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s2 + ScaleOffset.s3; + weights3 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s2 + ScaleOffset.s3; + } + PADZEROS(k, srcChannel, weights0); + PADZEROS(k + 15, srcChannel, weights1); + PADZEROS(k, srcChannel, weights2); + PADZEROS(k + 15, srcChannel, weights3); + { + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 7) * wh) : (FLOAT4)0); + + DOT16X16(in0, weights0, out.s0); + DOT16X16(in1, weights1, out.s0); + DOT16X16(in0, weights2, out.s1); + DOT16X16(in1, weights3, out.s1); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 7) * wh) : (FLOAT4)0); + + DOT16X16(in0, weights0, out1.s0); + DOT16X16(in1, weights1, out1.s0); + DOT16X16(in0, weights2, out1.s1); + DOT16X16(in1, weights3, out1.s1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 7) * wh) : (FLOAT4)0); + + DOT16X16(in0, weights0, out2.s0); + DOT16X16(in1, weights1, out2.s0); + DOT16X16(in0, weights2, out2.s1); + DOT16X16(in1, weights3, out2.s1); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 7) * wh) : (FLOAT4)0); + + DOT16X16(in0, weights0, out3.s0); + DOT16X16(in1, weights1, out3.s0); + DOT16X16(in0, weights2, out3.s1); + DOT16X16(in1, weights3, out3.s1); + } + #endif } -#endif + #endif + #endif //USE_LOW_BIT_WEIGHT_INT4 } -#endif -#endif //USE_LOW_BIT_WEIGHT_INT4 - out = bias0 + mad(out, Scale, sum * Offset); #ifdef RELU out = fmax(out, (COMPUTE_FLOAT2)0); #endif @@ -1220,7 +1202,6 @@ __kernel void gemm_conv_c2_image(GLOBAL_SIZE_DIM2 #ifdef BACTH_BLOCK4 if(isValidBatch1){ out_offset += dstChannelC4 * height * width * 4; - out1 = bias0 + mad(out1, Scale, sum1 * Offset); #ifdef RELU out1 = fmax(out1, (COMPUTE_FLOAT2)0); #endif @@ -1233,7 +1214,6 @@ __kernel void gemm_conv_c2_image(GLOBAL_SIZE_DIM2 } if(isValidBatch2){ out_offset += dstChannelC4 * height * width * 4; - out2 = bias0 + mad(out2, Scale, sum2 * Offset); #ifdef RELU out2 = fmax(out2, (COMPUTE_FLOAT2)0); #endif @@ -1246,7 +1226,6 @@ __kernel void gemm_conv_c2_image(GLOBAL_SIZE_DIM2 } if(isValidBatch3){ out_offset += dstChannelC4 * height * width * 4; - out3 = bias0 + mad(out3, Scale, sum3 * Offset); #ifdef RELU out3 = fmax(out3, (COMPUTE_FLOAT2)0); #endif @@ -1262,15 +1241,17 @@ __kernel void gemm_conv_c2_image(GLOBAL_SIZE_DIM2 __kernel void gemm_conv_c1_image(GLOBAL_SIZE_DIM2 __global const FLOAT* input, __read_only image2d_t weight, - __global const float *dequantScale, - __global const float *dequantOffset, + __global const float *dequantScaleOffset, __global const FLOAT *bias, __global FLOAT* output, __private const int dstChannelC4, __private const int srcChannelC4, + __private const int srcChannel, __private const int batch, __private const int height, - __private const int width) { + __private const int width, + __private const int blockNum, + __private const int blockDim) { const int out_c_w_idx = get_global_id(0); //c/4 w const int out_b_h_idx = get_global_id(1); //b h UNIFORM_BOUNDRY_CHECK(out_c_w_idx, out_b_h_idx); @@ -1285,17 +1266,13 @@ __kernel void gemm_conv_c1_image(GLOBAL_SIZE_DIM2 const int out_h_idx = out_b_h_idx % height; COMPUTE_FLOAT bias0 = bias[out_c_idx]; - COMPUTE_FLOAT out = 0; - COMPUTE_FLOAT sum = 0; + COMPUTE_FLOAT out = bias0; int input_offset = ((out_b_idx * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int out_offset = (((out_b_idx * dstChannelC4 + out_c_idx/4)* height + out_h_idx) * width + out_w_idx) * 4 + (out_c_idx%4); -#ifndef WIDTH_HEIGHT_1 int wh = width * height * 4; -#endif #ifdef BACTH_BLOCK4 - COMPUTE_FLOAT sum1 = 0, sum2 = 0, sum3 = 0; - COMPUTE_FLOAT out1 = 0, out2 = 0, out3 = 0; + COMPUTE_FLOAT out1 = bias0, out2 = bias0, out3 = bias0; int input_offset1 = (((out_b_idx + 1) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset2 = (((out_b_idx + 2) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; int input_offset3 = (((out_b_idx + 3) * srcChannelC4 * height + out_h_idx) * width + out_w_idx) * 4; @@ -1303,356 +1280,340 @@ __kernel void gemm_conv_c1_image(GLOBAL_SIZE_DIM2 bool isValidBatch2 = out_b_idx + 2 < batch; bool isValidBatch3 = out_b_idx + 3 < batch; #endif - const COMPUTE_FLOAT Scale = dequantScale[out_c_idx]; - const COMPUTE_FLOAT Offset = dequantOffset[out_c_idx]; - + #if (defined USE_LOW_BIT_WEIGHT_INT8) -#ifdef INPUT_CHANNEL_LEAVE - const int srcChannelC16 = (srcChannelC4 + 3) >> 2; - for (int k = 0; k < srcChannelC16-1; k++) { -#else - for (int k = 0; k < srcChannelC4/4; k++) { -#endif -#ifndef WIDTH_HEIGHT_1 - int k4 = k * 4; -#endif - COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k)))); - { - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); -#endif - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); -#endif - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); -#endif - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; -#ifdef WIDTH_HEIGHT_1 - in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 16)); -#else - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); - in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); - in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); -#endif - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3); - } -#endif - } -#ifdef INPUT_CHANNEL_LEAVE - { - int k = srcChannelC16 - 1; - int k4 = k * 4; - COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k)))); - { - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); - sum += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); - sum1 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); - sum2 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out2); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in; - in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); - in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); - in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); - in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); - sum3 += in.s0 + in.s1 + in.s2 + in.s3 + in.s4 + in.s5 + in.s6 + in.s7 + in.s8 + in.s9 + in.sa + in.sb + in.sc + in.sd + in.se + in.sf; - DOT16X16(in, weights0, out3); - } -#endif - } -#endif + const int loop = (blockDim + 15) / 16; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + #else + const int loop_end = loop; + #endif #elif (defined USE_LOW_BIT_WEIGHT_INT4) -#ifdef INPUT_CHANNEL_LEAVE - const int srcChannelC32 = (srcChannelC4 + 7) >> 3; - for (int k = 0; k < srcChannelC32-1; k++) { -#else - for (int k = 0; k < srcChannelC4/8; k++) { + const int loop = (blockDim + 31) / 32; + #ifdef INPUT_CHANNEL_LEAVE + const int loop_end = max(loop - 1, 0); + #else + const int loop_end = loop; + #endif #endif -#ifndef WIDTH_HEIGHT_1 - int k8 = k * 8; -#endif - COMPUTE_FLOAT16 weights0, weights1; - { - uchar16 charWeightsInt4 = as_uchar16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k))); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); + + for (int i = 0; i < blockNum; ++i){ + int kindex = i * dstChannelC4 * 4 * 2; + COMPUTE_FLOAT2 ScaleOffset = CONVERT_COMPUTE_FLOAT2(vload2(out_c_idx, dequantScaleOffset + kindex)); + #if (defined USE_LOW_BIT_WEIGHT_INT8) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + #ifndef WIDTH_HEIGHT_1 + int k4 = k << 2; + #endif + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + { + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out); + } + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out2); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + #ifdef WIDTH_HEIGHT_1 + in = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 16)); + #else + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 1) * wh)); + in.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 2) * wh)); + in.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k4 + 3) * wh)); + #endif + DOT16X16(in, weights0, out3); + } + #endif } + #ifdef INPUT_CHANNEL_LEAVE { - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 3) * wh)); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 7) * wh)); + int k = i * loop + loop_end; + int k4 = k << 2; + COMPUTE_FLOAT16 weights0 = CONVERT_COMPUTE_FLOAT16(as_char16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k)))) * ScaleOffset.s0 + ScaleOffset.s1; + { + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out); + } + PADZEROS(k, srcChannel, weights0); + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out2); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in; + in.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k4 * wh)); + in.s4567 = CONVERT_COMPUTE_FLOAT4(k4 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 1) * wh) : (FLOAT4)0); + in.s89ab = CONVERT_COMPUTE_FLOAT4(k4 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 2) * wh) : (FLOAT4)0); + in.scdef = CONVERT_COMPUTE_FLOAT4(k4 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k4 + 3) * wh) : (FLOAT4)0); + DOT16X16(in, weights0, out3); + } + #endif + } + #endif + #elif (defined USE_LOW_BIT_WEIGHT_INT4) + for (int j = 0; j < loop_end; j++) { + int k = i * loop + j; + #ifndef WIDTH_HEIGHT_1 + int k8 = k << 3; + #endif + COMPUTE_FLOAT16 weights0, weights1; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + { + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 3) * wh)); -#endif - sum += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out); - DOT16X16(in1, weights1, out); - } + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + (k8 + 7) * wh)); + #endif + DOT16X16(in0, weights0, out); + DOT16X16(in1, weights1, out); + } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 3) * wh)); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 7) * wh)); -#endif - sum1 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum1 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out1); - DOT16X16(in1, weights1, out1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 3) * wh)); + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset1 + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 3) * wh)); - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 7) * wh)); -#endif - sum2 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum2 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out2); - DOT16X16(in1, weights1, out2); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in0, in1; -#ifdef WIDTH_HEIGHT_1 - in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32)); - in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32 + 16)); -#else - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 1) * wh)); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 2) * wh)); - in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 3) * wh)); + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + (k8 + 7) * wh)); + #endif + DOT16X16(in0, weights0, out1); + DOT16X16(in1, weights1, out1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset2 + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 3) * wh)); - in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 4) * wh)); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 5) * wh)); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 6) * wh)); - in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 7) * wh)); -#endif - sum3 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum3 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out3); - DOT16X16(in1, weights1, out3); - } -#endif - } + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + (k8 + 7) * wh)); + #endif + DOT16X16(in0, weights0, out2); + DOT16X16(in1, weights1, out2); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in0, in1; + #ifdef WIDTH_HEIGHT_1 + in0 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32)); + in1 = CONVERT_COMPUTE_FLOAT16(vload16(0, input + input_offset3 + k * 32 + 16)); + #else + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 1) * wh)); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 2) * wh)); + in0.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 3) * wh)); -#ifdef INPUT_CHANNEL_LEAVE - { - int k = srcChannelC32 - 1; - int k8 = k * 8; - COMPUTE_FLOAT16 weights0, weights1; - { - uchar16 charWeightsInt4 = as_uchar16(read_imagef(weight, SAMPLER, (int2)(out_c_idx, k))); - char16 charWeights0 = 0; - char16 charWeights1 = 0; - UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); - weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0); - weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1); + in1.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 4) * wh)); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 5) * wh)); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 6) * wh)); + in1.scdef = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + (k8 + 7) * wh)); + #endif + DOT16X16(in0, weights0, out3); + DOT16X16(in1, weights1, out3); + } + #endif } + #ifdef INPUT_CHANNEL_LEAVE { - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 3) * wh) : (FLOAT4)0); + int k = i * loop + loop_end; + int k8 = k << 3; + COMPUTE_FLOAT16 weights0, weights1; + { + uchar16 charWeightsInt4 = as_uchar16(read_imagei(weight, SAMPLER, (int2)(out_c_idx, k))); + char16 charWeights0 = 0; + char16 charWeights1 = 0; + UCHAR16_TO_2CHAR16(charWeights0, charWeights1, charWeightsInt4); + weights0 = CONVERT_COMPUTE_FLOAT16(charWeights0) * ScaleOffset.s0 + ScaleOffset.s1; + weights1 = CONVERT_COMPUTE_FLOAT16(charWeights1) * ScaleOffset.s0 + ScaleOffset.s1; + } + PADZEROS(k, srcChannel, weights0); + PADZEROS(k + 15, srcChannel, weights1); + { + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 7) * wh) : (FLOAT4)0); + DOT16X16(in0, weights0, out); + DOT16X16(in1, weights1, out); + } - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset + (k8 + 7) * wh) : (FLOAT4)0); - sum += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in0, weights0, out); - DOT16X16(in1, weights1, out); - } -#ifdef BACTH_BLOCK4 - if(isValidBatch1){ - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < vload4(0, input + input_offset1 + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < vload4(0, input + input_offset1 + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < vload4(0, input + input_offset1 + (k8 + 3) * wh) : (FLOAT4)0); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 7) * wh) : (FLOAT4)0); - sum1 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum1 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in2, weights0, out1); - DOT16X16(in3, weights1, out1); - } - if(isValidBatch2){ - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < vload4(0, input + input_offset2 + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < vload4(0, input + input_offset2 + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < vload4(0, input + input_offset2 + (k8 + 3) * wh) : (FLOAT4)0); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 7) * wh) : (FLOAT4)0); - sum2 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum2 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in2, weights0, out2); - DOT16X16(in3, weights1, out2); - } - if(isValidBatch3){ - COMPUTE_FLOAT16 in0, in1; - in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k8 * wh)); - in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < vload4(0, input + input_offset3 + (k8 + 1) * wh) : (FLOAT4)0); - in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < vload4(0, input + input_offset3 + (k8 + 2) * wh) : (FLOAT4)0); - in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < vload4(0, input + input_offset3 + (k8 + 3) * wh) : (FLOAT4)0); - - in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 4) * wh) : (FLOAT4)0); - in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 5) * wh) : (FLOAT4)0); - in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 6) * wh) : (FLOAT4)0); - in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 7) * wh) : (FLOAT4)0); - sum3 += in0.s0 + in0.s1 + in0.s2 + in0.s3 + in0.s4 + in0.s5 + in0.s6 + in0.s7 + in0.s8 + in0.s9 + in0.sa + in0.sb + in0.sc + in0.sd + in0.se + in0.sf; - sum3 += in1.s0 + in1.s1 + in1.s2 + in1.s3 + in1.s4 + in1.s5 + in1.s6 + in1.s7 + in1.s8 + in1.s9 + in1.sa + in1.sb + in1.sc + in1.sd + in1.se + in1.sf; - DOT16X16(in2, weights0, out3); - DOT16X16(in3, weights1, out3); + #ifdef BACTH_BLOCK4 + if(isValidBatch1){ + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset1 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset1 + (k8 + 7) * wh) : (FLOAT4)0); + DOT16X16(in0, weights0, out1); + DOT16X16(in1, weights1, out1); + } + if(isValidBatch2){ + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset2 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset2 + (k8 + 7) * wh) : (FLOAT4)0); + DOT16X16(in0, weights0, out2); + DOT16X16(in1, weights1, out2); + } + if(isValidBatch3){ + COMPUTE_FLOAT16 in0, in1; + in0.s0123 = CONVERT_COMPUTE_FLOAT4(vload4(0, input + input_offset3 + k8 * wh)); + in0.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 1 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 1) * wh) : (FLOAT4)0); + in0.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 2 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 2) * wh) : (FLOAT4)0); + in0.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 3 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 3) * wh) : (FLOAT4)0); + + in1.s0123 = CONVERT_COMPUTE_FLOAT4(k8 + 4 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 4) * wh) : (FLOAT4)0); + in1.s4567 = CONVERT_COMPUTE_FLOAT4(k8 + 5 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 5) * wh) : (FLOAT4)0); + in1.s89ab = CONVERT_COMPUTE_FLOAT4(k8 + 6 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 6) * wh) : (FLOAT4)0); + in1.scdef = CONVERT_COMPUTE_FLOAT4(k8 + 7 < srcChannelC4 ? vload4(0, input + input_offset3 + (k8 + 7) * wh) : (FLOAT4)0); + DOT16X16(in0, weights0, out3); + DOT16X16(in1, weights1, out3); + } + #endif } -#endif + #endif + #endif //USE_LOW_BIT_WEIGHT_INT4 } -#endif -#endif //USE_LOW_BIT_WEIGHT_INT4 - out = bias0 + mad(out, Scale, sum * Offset); #ifdef RELU - out = fmax(out, 0); + out = fmax(out, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out = clamp(out, 0, 6); + out = clamp(out, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out; #ifdef BACTH_BLOCK4 if(isValidBatch1){ out_offset += dstChannelC4 * height * width * 4; - out1 = bias0 + mad(out1, Scale, sum1 * Offset); #ifdef RELU - out1 = fmax(out1, 0); + out1 = fmax(out1, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out1 = clamp(out1, 0, 6); + out1 = clamp(out1, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out1; } if(isValidBatch2){ out_offset += dstChannelC4 * height * width * 4; - out2 = bias0 + mad(out2, Scale, sum2 * Offset); #ifdef RELU - out2 = fmax(out2, 0); + out2 = fmax(out2, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out1 = clamp(out2, 0, 6); + out1 = clamp(out2, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out2; } if(isValidBatch3){ out_offset += dstChannelC4 * height * width * 4; - out3 = bias0 + mad(out3, Scale, sum3 * Offset); #ifdef RELU - out3 = fmax(out3, 0); + out3 = fmax(out3, (COMPUTE_FLOAT)0); #endif #ifdef RELU6 - out3 = clamp(out3, 0, 6); + out3 = clamp(out3, (COMPUTE_FLOAT)0, (COMPUTE_FLOAT)6); #endif output[out_offset] = out3; diff --git a/source/backend/opencl/execution/cl/groupnorm_buf.cl b/source/backend/opencl/execution/cl/groupnorm_buf.cl new file mode 100644 index 000000000..59e848dff --- /dev/null +++ b/source/backend/opencl/execution/cl/groupnorm_buf.cl @@ -0,0 +1,243 @@ +#ifdef MNN_SUPPORT_FP16 +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +#endif + +__kernel void groupnorm_plain_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, +#ifdef DOUBLE_INPUTS + __global const FLOAT * input0, + __global const FLOAT * input1, +#else + __global const FLOAT * input, +#endif + __global FLOAT * output, + __private const int area, + __private const int group, + __private const int inside, + __private const int outside, +#ifdef GAMMA_BETA + __global const FLOAT *gamma, + __global const FLOAT *beta, +#endif + __private float epsilon){ + int3 pos = (int3)(get_global_id(0), get_global_id(1), get_global_id(2)); + float local sum[LOCAL_SIZE]; + if (pos.x < global_dim0 && pos.y < global_dim1 && pos.z < global_dim2) { + const int idx_out = pos.z; + const int lid = get_local_id(0); + const int offset = idx_out * inside; + const int inside_v4 = (inside + 3) >> 2; + +#ifdef DOUBLE_INPUTS + // The product of W and H is a multiple of 4 + #ifdef WH_4 + float4 in_sum = 0; + int index = lid; + for(; index < inside_v4; index+=LOCAL_SIZE){ + float4 in0 = convert_float4(vload4(index, input0 + offset)); + in_sum += in0; + float in1 = input1[idx_out * (inside/area) + index / (area/4)]; + in_sum += (float4)(in1, in1, in1, in1); + } + sum[lid] = in_sum.x + in_sum.y + in_sum.z+ in_sum.w; + + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + + + float4 mean = sum[0] / (float4)inside; + + in_sum = 0; + index = lid; + for(; index < inside_v4; index+=LOCAL_SIZE){ + float4 in0 = convert_float4(vload4(index, input0 + offset)); + float in1 = input1[idx_out * (inside/area) + index / (area/4)]; + in_sum += (in0 + (float4)(in1, in1, in1, in1) - mean) * (in0 + (float4)in1 - mean); + } + sum[lid] = in_sum.x + in_sum.y + in_sum.z + in_sum.w; + + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + float4 square_sum = sum[0] / (float4)inside; + float4 value = (float4)1.0f / (float4)sqrt(square_sum + (float4)epsilon); + + for(int i = lid; i < inside_v4; i+=LOCAL_SIZE){ + float4 in0 = convert_float4(vload4(i, input0 + offset)); + float in1 = input1[idx_out * (inside/area) + i / (area/4)]; + float4 out = (in0 + (float4)(in1, in1, in1, in1) - mean) * value; + + #ifdef GAMMA_BETA + int offset_gamma_beta = (idx_out % group) * inside/area + i / (area/4); + out = out * (float4)((float)gamma[offset_gamma_beta]) + (float4)((float)beta[offset_gamma_beta]); + #endif + + #ifdef SWISH + out = out * native_recip((float4)1+native_exp(convert_float4(-out))); + #endif + vstore4(CONVERT_FLOAT4(out), i, output + offset); + } + #else + + float in_sum = 0; + int index = lid; + for(; index < inside; index+=LOCAL_SIZE){ + float in0 = input0[offset + index]; + in_sum += in0; + float in1 = input1[idx_out * (inside/area) + index / area]; + in_sum += in1; + } + sum[lid] = in_sum; + + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + + + float mean = sum[0] / inside; + + in_sum = 0; + index = lid; + for(; index < inside; index+=LOCAL_SIZE){ + float in0 = input0[offset + index]; + float in1 = input1[idx_out * (inside/area) + index / area]; + in_sum += (in0 + in1 - mean) * (in0 + in1 - mean); + } + sum[lid] = in_sum; + + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + float square_sum = sum[0] / inside; + float value = 1.0f / sqrt(square_sum + epsilon); + + for(int i = lid; i < inside; i+=LOCAL_SIZE){ + float in0 = input0[offset + i]; + float in1 = input1[idx_out * (inside/area) + i / area]; + float out = (in0 + in1 - mean) * value; + + #ifdef GAMMA_BETA + int offset_gamma_beta = (idx_out % group) * inside/area + i / area; + out = out * (float)gamma[offset_gamma_beta] + (float)beta[offset_gamma_beta]; + #endif + + #ifdef SWISH + out = out * native_recip(1.0+native_exp(-out)); + #endif + output[offset+i] = (FLOAT)out; + } + + #endif +#else + const int inside_remain = inside - ((inside_v4-1) << 2); + + float4 in_sum = 0; + int index = lid; + for(; index < inside_v4 - 1; index+=LOCAL_SIZE){ + float4 in = convert_float4(vload4(index, input + offset)); + in_sum += in; + } + sum[lid] = in_sum.x + in_sum.y + in_sum.z+ in_sum.w; + + float4 in_left = 0; + if(index == inside_v4 - 1) { + in_left = convert_float4(vload4(inside_v4 - 1, input + offset)); + sum[lid] = sum[lid] + in_left.x; + if(inside_remain > 1) { + sum[lid] = sum[lid] + in_left.y; + } + if(inside_remain > 2) { + sum[lid] = sum[lid] + in_left.z; + } + if(inside_remain > 3) { + sum[lid] = sum[lid] + in_left.w; + } + } + + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + + float4 mean = sum[0] / (float4)inside; + + in_sum = 0; + index = lid; + for(; index < inside_v4 - 1; index+=LOCAL_SIZE){ + float4 in = convert_float4(vload4(index, input + offset)); + in_sum += (in - mean) * (in - mean); + } + sum[lid] = in_sum.x + in_sum.y + in_sum.z + in_sum.w; + + if(index == inside_v4 - 1) { + float4 in_left = convert_float4(vload4(inside_v4 - 1, input + offset)); + in_sum = (in_left - mean) * (in_left - mean); + sum[lid] = sum[lid] + in_sum.x; + if(inside_remain > 1) { + sum[lid] = sum[lid] + in_sum.y; + } + if(inside_remain > 2) { + sum[lid] = sum[lid] + in_sum.z; + } + if(inside_remain > 3) { + sum[lid] = sum[lid] + in_sum.w; + } + } + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + float4 square_sum = sum[0] / (float4)inside; + float4 value = (float4)1.0f / (float4)sqrt(square_sum + (float4)epsilon); + + // The product of W and H is a multiple of 4 + #ifdef WH_4 + for(int i = lid; i < inside_v4; i+=LOCAL_SIZE){ + float4 in = convert_float4(vload4(i, input + offset)); + float4 out = (in - mean) * value; + + #ifdef GAMMA_BETA + int offset_gamma_beta = (idx_out % group) * inside/area + i / (area/4); + out = out * (float4)((float)gamma[offset_gamma_beta]) + (float4)((float)beta[offset_gamma_beta]); + #endif + + #ifdef SWISH + out = out * native_recip((float4)1+native_exp(convert_float4(-out))); + #endif + vstore4(CONVERT_FLOAT4(out), i, output + offset); + } + #else + for(int i = lid; i < inside; i+=LOCAL_SIZE){ + float in = input[offset+i]; + float out = (in - mean.x) * value.x; + + #ifdef GAMMA_BETA + int offset_gamma_beta = (idx_out % group) * inside/area + i / area; + out = out * (float)gamma[offset_gamma_beta] + (float)beta[offset_gamma_beta]; + #endif + + #ifdef SWISH + out = out * native_recip(1.0+native_exp(-out)); + #endif + output[offset+i] = (FLOAT)out; + } + #endif +#endif + } +} diff --git a/source/backend/opencl/execution/cl/layernorm_buf.cl b/source/backend/opencl/execution/cl/layernorm_buf.cl index 3608a7af5..3ee18e085 100644 --- a/source/backend/opencl/execution/cl/layernorm_buf.cl +++ b/source/backend/opencl/execution/cl/layernorm_buf.cl @@ -249,14 +249,15 @@ __kernel void layernorm_plain_buf(__private int global_dim0, __private int globa const int inside_remain = inside - ((inside_v4-1) << 2); COMPUTE_FLOAT4 in_sum = 0; - for(int i = lid; i < inside_v4 - 1; i+=LOCAL_SIZE){ - COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(i, input + offset)); + int index = lid; + for(; index < inside_v4 - 1; index+=LOCAL_SIZE){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(index, input + offset)); in_sum += in; } sum[lid] = in_sum.x + in_sum.y + in_sum.z+ in_sum.w; COMPUTE_FLOAT4 in_left = 0; - if(lid == inside_v4 - 1) { + if(index == inside_v4 - 1) { in_left = CONVERT_COMPUTE_FLOAT4(vload4(inside_v4 - 1, input + offset)); sum[lid] = sum[lid] + in_left.x; if(inside_remain > 1) { @@ -280,13 +281,14 @@ __kernel void layernorm_plain_buf(__private int global_dim0, __private int globa COMPUTE_FLOAT4 mean = sum[0] / (COMPUTE_FLOAT4)inside; in_sum = 0; - for(int i = lid; i < inside_v4 - 1; i+=LOCAL_SIZE){ - COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(i, input + offset)); + index = lid; + for(; index < inside_v4 - 1; index+=LOCAL_SIZE){ + COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(index, input + offset)); in_sum += (in - mean) * (in - mean); } sum[lid] = in_sum.x + in_sum.y + in_sum.z + in_sum.w; - if(lid == inside_v4 - 1) { + if(index == inside_v4 - 1) { COMPUTE_FLOAT4 in_left = CONVERT_COMPUTE_FLOAT4(vload4(inside_v4 - 1, input + offset)); in_sum = (in_left - mean) * (in_left - mean); sum[lid] = sum[lid] + in_sum.x; @@ -308,11 +310,7 @@ __kernel void layernorm_plain_buf(__private int global_dim0, __private int globa } COMPUTE_FLOAT4 square_sum = sum[0] / (COMPUTE_FLOAT4)inside; COMPUTE_FLOAT4 value = (COMPUTE_FLOAT4)1.0f / (COMPUTE_FLOAT4)sqrt(square_sum + (COMPUTE_FLOAT4)epsilon); - /* - if(pos.x == 0) { - printf("ln: %d, mean:%f square:%f, value:%f\n", pos.z, (float)mean.x, (float)sum[0], (float)value.x); - } - */ + for(int i = lid; i < inside_v4; i+=LOCAL_SIZE){ COMPUTE_FLOAT4 in = CONVERT_COMPUTE_FLOAT4(vload4(i, input + offset)); #ifdef GAMMA_BETA diff --git a/source/backend/opencl/execution/cl/loop_buf.cl b/source/backend/opencl/execution/cl/loop_buf.cl index c73eaa11a..de7cb5725 100644 --- a/source/backend/opencl/execution/cl/loop_buf.cl +++ b/source/backend/opencl/execution/cl/loop_buf.cl @@ -3,13 +3,13 @@ #endif #define PI 3.141592653589f #ifndef WGSW - #define WGSW 64 // work-group handle size W dimension + #define WGSW 32 // work-group handle size W dimension #endif #ifndef WGSC - #define WGSC 64 // work-group handle size C dimension + #define WGSC 32 // work-group handle size C dimension #endif #ifndef WGSH - #define WGSH 64 // work-group handle size H dimension + #define WGSH 32 // work-group handle size H dimension #endif #ifndef TSW #define TSW 8 // thread handle size W dimension @@ -409,6 +409,7 @@ __kernel void broadcast_binary_buf(__private int global_dim0, __private int glob const int ho = pos.y; const int co = pos.z % channel_block; const int no = pos.z / channel_block; + const int output_offset = ((((no * channel_block) + co) * dst_height + ho) * dst_width + wo) * 4; int co4 = co << 2; int4 covec = (int4)(co4 % dst_channel, (co4 + 1) % dst_channel, (co4 + 2) % dst_channel, (co4 + 3) % dst_channel); int4 out_offset = ((no * dst_channel + covec) * dst_height + ho) * dst_width + wo; @@ -416,56 +417,129 @@ __kernel void broadcast_binary_buf(__private int global_dim0, __private int glob int4 h = out_offset % dst_size.s2; out_offset /= dst_size.s2; int4 c = out_offset % dst_size.s1; out_offset /= dst_size.s1; int4 n = out_offset % dst_size.s0; - const int src0_channel_block = (src0C4_size.z + 3) / 4; - const int src1_channel_block = (src1C4_size.z + 3) / 4; float4 in0, in1; - float* in0_ptr = (float*)&in0; + +#ifdef BROADCAST_INPUT1 + in0 = convert_float4(vload4(0, input0 + output_offset)); + const int src1_channel_block = (src1C4_size.y + 3) / 4; float* in1_ptr = (float*)&in1; - { - int4 w0 = w % (src0_size.s3 * src0_size.s4); - int4 h0 = h % src0_size.s2; - int4 c0 = c % src0_size.s1; - int4 n0 = n % src0_size.s0; + int4 w0 = w % (src1_size.s3 * src1_size.s4); + int4 h0 = h % src1_size.s2; + int4 c0 = c % src1_size.s1; + int4 n0 = n % src1_size.s0; int* w0_ptr = (int*)&w0; int* h0_ptr = (int*)&h0; int* c0_ptr = (int*)&c0; int* n0_ptr = (int*)&n0; for(int i = 0; i < 4; ++i){ - int c4offset = ((n0_ptr[i] * src0_size.s1 + c0_ptr[i]) * src0_size.s2 + h0_ptr[i]) * src0_size.s3 * src0_size.s4 + w0_ptr[i]; - int wc4 = c4offset % src0C4_size.x; c4offset /= src0C4_size.x; - int hc4 = c4offset % src0C4_size.y; c4offset /= src0C4_size.y; - int cc4 = c4offset % src0C4_size.z; c4offset /= src0C4_size.z; - int nc4 = c4offset % src0C4_size.w; + int c4offset = ((n0_ptr[i] * src1_size.s1 + c0_ptr[i]) * src1_size.s2 + h0_ptr[i]) * src1_size.s3 * src1_size.s4 + w0_ptr[i]; + int wc4 = c4offset % src1C4_size.w; c4offset /= src1C4_size.w; + int hc4 = c4offset % src1C4_size.z; c4offset /= src1C4_size.z; + int cc4 = c4offset % src1C4_size.y; c4offset /= src1C4_size.y; + int nc4 = c4offset % src1C4_size.x; int cc4_offset = cc4 / 4; int cc4_remain = cc4 % 4; - in0_ptr[i] = (float)input0[((((nc4 * src0_channel_block) + cc4_offset) * src0C4_size.y + hc4) * src0C4_size.x + wc4) * 4 + cc4_remain]; + in1_ptr[i] = (float)input1[((((nc4 * src1_channel_block) + cc4_offset) * src1C4_size.z + hc4) * src1C4_size.w + wc4) * 4 + cc4_remain]; } } - +#else + const int src0_channel_block = (src0C4_size.y + 3) / 4; + float* in0_ptr = (float*)&in0; { - int4 w0 = w % (src1_size.s3 * src1_size.s4); - int4 h0 = h % src1_size.s2; - int4 c0 = c % src1_size.s1; - int4 n0 = n % src1_size.s0; + int4 w0 = w % (src0_size.s3 * src0_size.s4); + int4 h0 = h % src0_size.s2; + int4 c0 = c % src0_size.s1; + int4 n0 = n % src0_size.s0; int* w0_ptr = (int*)&w0; int* h0_ptr = (int*)&h0; int* c0_ptr = (int*)&c0; int* n0_ptr = (int*)&n0; for(int i = 0; i < 4; ++i){ - int c4offset = ((n0_ptr[i] * src1_size.s1 + c0_ptr[i]) * src1_size.s2 + h0_ptr[i]) * src1_size.s3 * src1_size.s4 + w0_ptr[i]; - int wc4 = c4offset % src1C4_size.x; c4offset /= src1C4_size.x; - int hc4 = c4offset % src1C4_size.y; c4offset /= src1C4_size.y; - int cc4 = c4offset % src1C4_size.z; c4offset /= src1C4_size.z; - int nc4 = c4offset % src1C4_size.w; + int c4offset = ((n0_ptr[i] * src0_size.s1 + c0_ptr[i]) * src0_size.s2 + h0_ptr[i]) * src0_size.s3 * src0_size.s4 + w0_ptr[i]; + int wc4 = c4offset % src0C4_size.w; c4offset /= src0C4_size.w; + int hc4 = c4offset % src0C4_size.z; c4offset /= src0C4_size.z; + int cc4 = c4offset % src0C4_size.y; c4offset /= src0C4_size.y; + int nc4 = c4offset % src0C4_size.x; int cc4_offset = cc4 / 4; int cc4_remain = cc4 % 4; - in1_ptr[i] = (float)input1[((((nc4 * src1_channel_block) + cc4_offset) * src1C4_size.y + hc4) * src1C4_size.x + wc4) * 4 + cc4_remain]; + in0_ptr[i] = (float)input0[((((nc4 * src0_channel_block) + cc4_offset) * src0C4_size.z + hc4) * src0C4_size.w + wc4) * 4 + cc4_remain]; } } + in1 = convert_float4(vload4(0, input1 + output_offset)); +#endif + float4 out = LOOP_BINARY_OPERATOR; + vstore4(CONVERT_OUTPUT4(out), 0, output + output_offset); + } +} + +__kernel void broadcast_binary_channel_equall_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, + __global OUTPUT_TYPE* output, __global INPUT_TYPE* input0, __global INPUT_TYPE* input1, + __private const int8 src0_size, //(batch, channel, height, width) + __private const int4 src0C4_size, // nc4hw4 + __private const int8 src1_size, + __private const int4 src1C4_size, + __private const int8 dst_size, + __private const int dst_width, + __private const int dst_height, + __private const int dst_channel, + __private const int channel_block) { + int3 pos = (int3)(get_global_id(0), get_global_id(1), get_global_id(2)); + + if (pos.x < global_dim0 && pos.y < global_dim1 && pos.z < global_dim2) { + const int wo = pos.x; + const int ho = pos.y; + const int co = pos.z % channel_block; + const int no = pos.z / channel_block; + const int output_offset = ((((no * channel_block) + co) * dst_height + ho) * dst_width + wo) * 4; +#ifdef BROADCAST_INPUT1 + const int src1_channel_block = (src1C4_size.y + 3) / 4; + const int input_offset = (((((no % src1_size.s0) * src1_channel_block) + co) * src1C4_size.z + (ho % src1_size.s2)) * src1C4_size.w + (wo % (src1_size.s3 * src1_size.s4))) * 4; + float4 in0 = convert_float4(vload4(0, input0 + output_offset)); + float4 in1 = convert_float4(vload4(0, input1 + input_offset)); +#else + const int src0_channel_block = (src0C4_size.y + 3) / 4; + const int input_offset = (((((no % src0_size.s0) * src0_channel_block) + co) * src0C4_size.z + (ho % src0_size.s2)) * src0C4_size.w + (wo % (src0_size.s3 * src0_size.s4))) * 4; + float4 in0 = convert_float4(vload4(0, input0 + input_offset)); + float4 in1 = convert_float4(vload4(0, input1 + output_offset)); +#endif + float4 out = LOOP_BINARY_OPERATOR; + vstore4(CONVERT_OUTPUT4(out), 0, output + output_offset); + } +} + +//channel = 1 and dimmision = 1 +__kernel void broadcast_binary_dimmision1_channel1_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, + __global OUTPUT_TYPE* output, __global INPUT_TYPE* input0, __global INPUT_TYPE* input1, + __private const int8 src0_size, //(batch, channel, height, width) + __private const int4 src0C4_size, // nc4hw4 + __private const int8 src1_size, + __private const int4 src1C4_size, + __private const int8 dst_size, + __private const int dst_width, + __private const int dst_height, + __private const int dst_channel, + __private const int channel_block) { + int3 pos = (int3)(get_global_id(0), get_global_id(1), get_global_id(2)); + + if (pos.x < global_dim0 && pos.y < global_dim1 && pos.z < global_dim2) { + const int wo = pos.x; + const int ho = pos.y; + const int co = pos.z % channel_block; + const int no = pos.z / channel_block; + const int output_offset = ((((no * channel_block) + co) * dst_height + ho) * dst_width + wo) * 4; +#ifdef BROADCAST_INPUT1 + const int input_offset = ((no % src1_size.s0) * src1_size.s2 + (ho % src1_size.s2)) * src1_size.s3 * src1_size.s4 + (wo % (src1_size.s3 * src1_size.s4)); + float4 in0 = convert_float4(vload4(0, input0 + output_offset)); + float4 in1 = (float4)(input1[input_offset]); +#else + const int input_offset = ((no % src0_size.s0) * src0_size.s2 + (ho % src0_size.s2)) * src0_size.s3 * src0_size.s4 + (wo % (src0_size.s3 * src0_size.s4)); + float4 in0 = (float4)(input0[input_offset]); + float4 in1 = convert_float4(vload4(0, input1 + output_offset)); +#endif float4 out = LOOP_BINARY_OPERATOR; - vstore4(CONVERT_OUTPUT4(out), 0, output + ((((no * channel_block) + co) * dst_height + ho) * dst_width + wo) * 4); + vstore4(CONVERT_OUTPUT4(out), 0, output + output_offset); } } #endif diff --git a/source/backend/opencl/execution/cl/matmul_params_buf.cl b/source/backend/opencl/execution/cl/matmul_params_buf.cl index 90f91c474..601dc50e6 100644 --- a/source/backend/opencl/execution/cl/matmul_params_buf.cl +++ b/source/backend/opencl/execution/cl/matmul_params_buf.cl @@ -74,37 +74,6 @@ #define GLOBAL_MEM_FENCE 0 // Global synchronisation barrier for potential better performance #endif -#ifndef SUBGROUP_SHUFFLING_NVIDIA_PRE_VOLTA - #define SUBGROUP_SHUFFLING_NVIDIA_PRE_VOLTA 0 -#endif -#ifndef SUBGROUP_SHUFFLING_NVIDIA_POST_VOLTA - #define SUBGROUP_SHUFFLING_NVIDIA_POST_VOLTA 0 -#endif -#ifndef SUBGROUP_SHUFFLING_INTEL - #define SUBGROUP_SHUFFLING_INTEL 0 -#endif -#ifndef USE_SUBGROUP_SHUFFLING - #define USE_SUBGROUP_SHUFFLING 0 // Optionally enables subgroup shuffling for Intel GPUs -#endif - -// Intel subgroups (https://www.khronos.org/registry/OpenCL/extensions/intel/cl_intel_subgroups.html) -#if USE_SUBGROUP_SHUFFLING == 1 && SUBGROUP_SHUFFLING_INTEL == 1 - #pragma OPENCL EXTENSION cl_intel_subgroups: enable - #define SUBGROUP_SIZE 8 // Assumes subgroup size is always 8 on Intel GPUs -#endif - -// NVIDIA warps as subgroups using inline PTX (https://docs.nvidia.com/cuda/inline-ptx-assembly/index.html) -#if USE_SUBGROUP_SHUFFLING == 1 - #if SUBGROUP_SHUFFLING_NVIDIA_PRE_VOLTA == 1 || SUBGROUP_SHUFFLING_NVIDIA_POST_VOLTA == 1 - #define SUBGROUP_SIZE 32 // Assumes subgroup size is always 32 on NVIDIA GPUs - #endif -#endif - -#if NWI != SUBGROUP_SIZE || MDIMC < SUBGROUP_SIZE - #undef USE_SUBGROUP_SHUFFLING - #define USE_SUBGROUP_SHUFFLING 0 // Disables subgroups in case the assumptions don't hold -#endif - // Half-precision #if PRECISION == 16 typedef half real; @@ -274,29 +243,8 @@ // ================================================================================================= -// Shuffled workgroup indices to avoid partition camping, see below. For specific devices, this is -// enabled (see src/routine.cc). -#ifndef USE_STAGGERED_INDICES - #define USE_STAGGERED_INDICES 0 -#endif - -// Staggered/shuffled group indices to avoid partition camping (AMD GPUs). Formula's are taken from: -// http://docs.nvidia.com/cuda/samples/6_Advanced/transpose/doc/MatrixTranspose.pdf -// More details: https://github.com/CNugteren/CLBlast/issues/53 -#if USE_STAGGERED_INDICES == 1 && GEMMK == 0 - INLINE_FUNC int GetGroupIDFlat() { - return get_group_id(0) + get_num_groups(0) * get_group_id(1); - } - INLINE_FUNC int GetGroupID1() { - return (GetGroupIDFlat()) % get_num_groups(1); - } - INLINE_FUNC int GetGroupID0() { - return ((GetGroupIDFlat() / get_num_groups(1)) + GetGroupID1()) % get_num_groups(0); - } -#else INLINE_FUNC int GetGroupID1() { return get_group_id(1); } INLINE_FUNC int GetGroupID0() { return get_group_id(0); } -#endif // ================================================================================================= @@ -373,6 +321,48 @@ INLINE_FUNC realM InitAccRegisters() { return result; } +INLINE_FUNC realN InitAccRegistersN() { + realN result; + #if VWN == 1 + SetToZero(result); + #elif VWN == 2 + SetToZero(result.x); + SetToZero(result.y); + #elif VWN == 4 + SetToZero(result.x); + SetToZero(result.y); + SetToZero(result.z); + SetToZero(result.w); + #elif VWN == 8 + SetToZero(result.s0); + SetToZero(result.s1); + SetToZero(result.s2); + SetToZero(result.s3); + SetToZero(result.s4); + SetToZero(result.s5); + SetToZero(result.s6); + SetToZero(result.s7); + #elif VWN == 16 + SetToZero(result.s0); + SetToZero(result.s1); + SetToZero(result.s2); + SetToZero(result.s3); + SetToZero(result.s4); + SetToZero(result.s5); + SetToZero(result.s6); + SetToZero(result.s7); + SetToZero(result.s8); + SetToZero(result.s9); + SetToZero(result.sA); + SetToZero(result.sB); + SetToZero(result.sC); + SetToZero(result.sD); + SetToZero(result.sE); + SetToZero(result.sF); + #endif + return result; +} + // ================================================================================================= // Caches global off-chip memory into local (shared) memory on-chip. This function is specific for @@ -477,57 +467,6 @@ INLINE_FUNC realN GlobalToPrivateB(const __global realN* restrict bgm, const int } #endif -// ================================================================================================= -#if GEMMK == 1 - -// Caches global off-chip memory directly into per-thread private memory (registers). This function -// is specific for caching the A input matrix for kernel 1. -INLINE_FUNC realN GlobalToPrivateA2D(const __global real* restrict a_ptr, const int tid_y, const int _ni, - const int kSizeK, const int idk, const int _ki) { - #if PRECISION == 3232 || PRECISION == 6464 - const int a_index = (tid_y * NWI + _ni) * (kSizeK / VWN) + idk / VWN + _ki; - const __global realN* restrict agm = (const __global realN* restrict) a_ptr; - return agm[a_index]; - #else - const int a_index = (tid_y * NWI + _ni) * kSizeK + idk + _ki * VWN; - #if VWN == 1 - return a_ptr[a_index]; - #elif VWN == 2 - return vload2(0, a_ptr + a_index); - #elif VWN == 4 - return vload4(0, a_ptr + a_index); - #elif VWN == 8 - return vload8(0, a_ptr + a_index); - #elif VWN == 16 - return vload16(0, a_ptr + a_index); - #endif - #endif -} - -// Same as above, but now for the B input matrix -INLINE_FUNC realM GlobalToPrivateB2D(const __global real* restrict b_ptr, const int tid_x, const int _mi, - const int kSizeN, const int idk, const int _ki) { - #if PRECISION == 3232 || PRECISION == 6464 - const int b_index = (idk + _ki) * (kSizeN / VWM) + tid_x * (MWI / VWM) + _mi; - const __global realM* restrict bgm = (const __global realM* restrict) b_ptr; - return bgm[b_index]; - #else - const int b_index = (idk + _ki) * kSizeN + tid_x * MWI + _mi * VWM; - #if VWM == 1 - return b_ptr[b_index]; - #elif VWM == 2 - return vload2(0, b_ptr + b_index); - #elif VWM == 4 - return vload4(0, b_ptr + b_index); - #elif VWM == 8 - return vload8(0, b_ptr + b_index); - #elif VWM == 16 - return vload16(0, b_ptr + b_index); - #endif - #endif -} - -#endif // ================================================================================================= // Caches on-chip local memory into per-thread private memory (registers). This function is specific @@ -603,6 +542,52 @@ INLINE_FUNC realM MultiplyAddVector(realM cvec, const realM avec, const real bva return cvec; } +// The vectorised multiply-add function +INLINE_FUNC realN MultiplyAddVectorN(realN cvec, const real avec, const realN bval) { + #if USE_VECTOR_MAD == 1 + cvec += avec * bval; + #else + #if VWN == 1 + MultiplyAdd(cvec, avec, bval); + #elif VWN == 2 + MultiplyAdd(cvec.x , avec, bval.x); + MultiplyAdd(cvec.y , avec, bval.y); + #elif VWN == 4 + MultiplyAdd(cvec.x , avec, bval.x); + MultiplyAdd(cvec.y , avec, bval.y); + MultiplyAdd(cvec.z , avec, bval.z); + MultiplyAdd(cvec.w , avec, bval.w); + #elif VWN == 8 + MultiplyAdd(cvec.s0, avec, bval.s0); + MultiplyAdd(cvec.s1, avec, bval.s1); + MultiplyAdd(cvec.s2, avec, bval.s2); + MultiplyAdd(cvec.s3, avec, bval.s3); + MultiplyAdd(cvec.s4, avec, bval.s4); + MultiplyAdd(cvec.s5, avec, bval.s5); + MultiplyAdd(cvec.s6, avec, bval.s6); + MultiplyAdd(cvec.s7, avec, bval.s7); + #elif VWN == 16 + MultiplyAdd(cvec.s0, avec, bval.s0); + MultiplyAdd(cvec.s1, avec, bval.s1); + MultiplyAdd(cvec.s2, avec, bval.s2); + MultiplyAdd(cvec.s3, avec, bval.s3); + MultiplyAdd(cvec.s4, avec, bval.s4); + MultiplyAdd(cvec.s5, avec, bval.s5); + MultiplyAdd(cvec.s6, avec, bval.s6); + MultiplyAdd(cvec.s7, avec, bval.s7); + MultiplyAdd(cvec.s8, avec, bval.s8); + MultiplyAdd(cvec.s9, avec, bval.s9); + MultiplyAdd(cvec.sA, avec, bval.sA); + MultiplyAdd(cvec.sB, avec, bval.sB); + MultiplyAdd(cvec.sC, avec, bval.sC); + MultiplyAdd(cvec.sD, avec, bval.sD); + MultiplyAdd(cvec.sE, avec, bval.sE); + MultiplyAdd(cvec.sF, avec, bval.sF); + #endif + #endif + return cvec; +} + // ================================================================================================= // Merges the results in Cpm with the global array in Cgm. This also performs the multiplication @@ -737,7 +722,91 @@ INLINE_FUNC void StoreResultsN(__global realN* cgn, realN c_value, int index = idm * (kSizeN/VWN) + idn; realN result = 0; - result = c_value; + realN xval = c_value; + + // The final multiplication with alpha (in case beta == 0) + if (IsZero(beta)) { + #if VWN == 1 + Multiply(result, alpha, xval); + #elif VWN == 2 + Multiply(result.x, alpha, xval.x); + Multiply(result.y, alpha, xval.y); + #elif VWN == 4 + Multiply(result.x, alpha, xval.x); + Multiply(result.y, alpha, xval.y); + Multiply(result.z, alpha, xval.z); + Multiply(result.w, alpha, xval.w); + #elif VWN == 8 + Multiply(result.s0, alpha, xval.s0); + Multiply(result.s1, alpha, xval.s1); + Multiply(result.s2, alpha, xval.s2); + Multiply(result.s3, alpha, xval.s3); + Multiply(result.s4, alpha, xval.s4); + Multiply(result.s5, alpha, xval.s5); + Multiply(result.s6, alpha, xval.s6); + Multiply(result.s7, alpha, xval.s7); + #elif VWN == 16 + Multiply(result.s0, alpha, xval.s0); + Multiply(result.s1, alpha, xval.s1); + Multiply(result.s2, alpha, xval.s2); + Multiply(result.s3, alpha, xval.s3); + Multiply(result.s4, alpha, xval.s4); + Multiply(result.s5, alpha, xval.s5); + Multiply(result.s6, alpha, xval.s6); + Multiply(result.s7, alpha, xval.s7); + Multiply(result.s8, alpha, xval.s8); + Multiply(result.s9, alpha, xval.s9); + Multiply(result.sA, alpha, xval.sA); + Multiply(result.sB, alpha, xval.sB); + Multiply(result.sC, alpha, xval.sC); + Multiply(result.sD, alpha, xval.sD); + Multiply(result.sE, alpha, xval.sE); + Multiply(result.sF, alpha, xval.sF); + #endif + } + + // The final multiplication with alpha and the addition with beta*C + else { + realN yval = cgn[index]; + #if VWN == 1 + AXPBY(result, alpha, xval, beta, yval); + #elif VWN == 2 + AXPBY(result.x, alpha, xval.x, beta, yval.x); + AXPBY(result.y, alpha, xval.y, beta, yval.y); + #elif VWN == 4 + AXPBY(result.x, alpha, xval.x, beta, yval.x); + AXPBY(result.y, alpha, xval.y, beta, yval.y); + AXPBY(result.z, alpha, xval.z, beta, yval.z); + AXPBY(result.w, alpha, xval.w, beta, yval.w); + #elif VWN == 8 + AXPBY(result.s0, alpha, xval.s0, beta, yval.s0); + AXPBY(result.s1, alpha, xval.s1, beta, yval.s1); + AXPBY(result.s2, alpha, xval.s2, beta, yval.s2); + AXPBY(result.s3, alpha, xval.s3, beta, yval.s3); + AXPBY(result.s4, alpha, xval.s4, beta, yval.s4); + AXPBY(result.s5, alpha, xval.s5, beta, yval.s5); + AXPBY(result.s6, alpha, xval.s6, beta, yval.s6); + AXPBY(result.s7, alpha, xval.s7, beta, yval.s7); + #elif VWN == 16 + AXPBY(result.s0, alpha, xval.s0, beta, yval.s0); + AXPBY(result.s1, alpha, xval.s1, beta, yval.s1); + AXPBY(result.s2, alpha, xval.s2, beta, yval.s2); + AXPBY(result.s3, alpha, xval.s3, beta, yval.s3); + AXPBY(result.s4, alpha, xval.s4, beta, yval.s4); + AXPBY(result.s5, alpha, xval.s5, beta, yval.s5); + AXPBY(result.s6, alpha, xval.s6, beta, yval.s6); + AXPBY(result.s7, alpha, xval.s7, beta, yval.s7); + AXPBY(result.s8, alpha, xval.s8, beta, yval.s8); + AXPBY(result.s9, alpha, xval.s9, beta, yval.s9); + AXPBY(result.sA, alpha, xval.sA, beta, yval.sA); + AXPBY(result.sB, alpha, xval.sB, beta, yval.sB); + AXPBY(result.sC, alpha, xval.sC, beta, yval.sC); + AXPBY(result.sD, alpha, xval.sD, beta, yval.sD); + AXPBY(result.sE, alpha, xval.sE, beta, yval.sE); + AXPBY(result.sF, alpha, xval.sF, beta, yval.sF); + #endif + } + #ifdef BIAS realN xval = egn[idn]; @@ -783,43 +852,7 @@ INLINE_FUNC void StoreResultsN(__global realN* cgn, realN c_value, cgn[index] = result; } -// A common interface for subgroup functions - -#if USE_SUBGROUP_SHUFFLING == 1 -INLINE_FUNC int clblast_get_sub_group_local_id() { - - // Intel extension - #if SUBGROUP_SHUFFLING_INTEL == 1 - return get_sub_group_local_id(); - - // Nvidia inline PTX - #elif SUBGROUP_SHUFFLING_NVIDIA_PRE_VOLTA == 1 || SUBGROUP_SHUFFLING_NVIDIA_POST_VOLTA == 1 - int ret; - asm volatile("mov.u32 %0, %%laneid;" : "=r"(ret) ); - return ret; - #endif -} - -INLINE_FUNC realN clblast_sub_group_shuffle(realN reg, int src) { - - // Intel extension - #if SUBGROUP_SHUFFLING_INTEL == 1 - return intel_sub_group_shuffle(reg, src); - - // Nvidia inline PTX - // Volta and later requires .sync shuffle instructions with an extra mask arg - #elif SUBGROUP_SHUFFLING_NVIDIA_PRE_VOLTA == 1 || SUBGROUP_SHUFFLING_NVIDIA_POST_VOLTA == 1 - realN ret; - #if SUBGROUP_SHUFFLING_NVIDIA_POST_VOLTA == 1 - asm volatile("shfl.sync.idx.b32 %0, %1, %2, 0x1f, 0xffffffff;" : "=f"(ret): "f"(reg), "r"(src)); - #else - asm volatile("shfl.idx.b32 %0, %1, %2, 0x1f;" : "=f"(ret): "f"(reg), "r"(src)); - #endif - return ret; - #endif -} -#endif // Main body of the matrix-multiplication algorithm. It calls various (inlined) functions. INLINE_FUNC void XgemmBody(const int kSizeM, const int kSizeN, const int kSizeK, @@ -838,30 +871,17 @@ INLINE_FUNC void XgemmBody(const int kSizeM, const int kSizeN, const int kSizeK, ) { // Allocates workitem-private memory (registers) - #if GEMMK == 0 - #pragma promote_to_registers - realM apm[MWI/VWM]; // MWI * 1 - #pragma promote_to_registers - realN bpm[NWI/VWN]; // 1 * NWI - #elif GEMMK == 1 - #if USE_SUBGROUP_SHUFFLING == 1 - #pragma promote_to_registers - realN apm[KREG/VWN]; // KREG (subgroup shuffling in NWI dimension) - #else - #pragma promote_to_registers - realN apm[NWI*(KREG/VWN)]; // NWI * KREG - #endif - #pragma promote_to_registers - realM bpm[KREG*(MWI/VWM)]; // KREG * MWI - #endif #pragma promote_to_registers - realM cpm[NWI*(MWI/VWM)]; // NWI * MWI + realM apm[MWI/VWM]; // MWI * 1 + #pragma promote_to_registers + realN bpm[NWI/VWN]; // 1 * NWI - #if GEMMK == 1 - const __global real* restrict a_ptr = (const __global real* restrict) &agm[0]; - const __global real* restrict b_ptr = (const __global real* restrict) &bgm[0]; - const int tid_x = get_local_id(0) + MDIMC * GetGroupID0(); - const int tid_y = get_local_id(1) + NDIMC * GetGroupID1(); + #ifdef OUTPUTMN + #pragma promote_to_registers + realN cpn[MWI*(NWI/VWN)]; // MWI * NWI + #else + #pragma promote_to_registers + realM cpm[NWI*(MWI/VWM)]; // NWI * MWI #endif // Combined thread identifier (volatile to disable caching) @@ -870,6 +890,15 @@ INLINE_FUNC void XgemmBody(const int kSizeM, const int kSizeN, const int kSizeK, #endif // Initializes the accumulation registers + #ifdef OUTPUTMN + #pragma unroll + for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { + #pragma unroll + for (int _mi = 0; _mi < MWI; _mi += 1) { + cpn[_mi * (NWI/VWN) + _ni] = InitAccRegistersN(); + } + } + #else #pragma unroll for (int _mi = 0; _mi < MWI/VWM; _mi += 1) { #pragma unroll @@ -877,6 +906,7 @@ INLINE_FUNC void XgemmBody(const int kSizeM, const int kSizeN, const int kSizeK, cpm[_ni * (MWI/VWM) + _mi] = InitAccRegisters(); } } + #endif // Loops over all workgroup tiles for (int kwg = 0; kwg < kSizeK; kwg += KWG * KREG) { @@ -913,147 +943,116 @@ INLINE_FUNC void XgemmBody(const int kSizeM, const int kSizeN, const int kSizeK, // Loads data: off-chip --> private (matrix A) #elif GEMMK == 0 && SA == 0 apm[_mi] = GlobalToPrivateA(agm, _mi, kSizeM, idk, kwg); - // Loads data: 2D global --> 2D private (matrix B) - #elif GEMMK == 1 - #pragma unroll - for (int _ki = 0; _ki < KREG; _ki += 1) { - bpm[_ki * (MWI/VWM) + _mi] = GlobalToPrivateB2D(b_ptr, tid_x, _mi, kSizeN, idk, _ki); - } #endif } // Loads matrix B (kernel 0) or matrix A (kernel 1) - #if GEMMK == 0 - #pragma unroll - for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { - // Loads data: local --> private (matrix B) - #if SB == 1 - bpm[_ni] = LocalToPrivateB(blm, _ni, kg); - // Loads data: off-chip --> private (matrix B) - #else - bpm[_ni] = GlobalToPrivateB(bgm, _ni, kSizeN, idk); - #endif - } - #elif GEMMK == 1 - // Loads data: 2D global --> 2D private (matrix A). Partly, shuffled later among subgroups - #if USE_SUBGROUP_SHUFFLING == 1 - const int _ni = clblast_get_sub_group_local_id(); - #pragma unroll - for (int _ki = 0; _ki < KREG/VWN; _ki += 1) { - apm[_ki] = GlobalToPrivateA2D(a_ptr, tid_y, _ni, kSizeK, idk, _ki); - } - // Loads data: 2D global --> 2D private (matrix A) + + #pragma unroll + for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { + // Loads data: local --> private (matrix B) + #if SB == 1 + bpm[_ni] = LocalToPrivateB(blm, _ni, kg); + // Loads data: off-chip --> private (matrix B) #else - #pragma unroll - for (int _ni = 0; _ni < NWI; _ni += 1) { - #pragma unroll - for (int _ki = 0; _ki < KREG/VWN; _ki += 1) { - apm[_ni * (KREG/VWN) + _ki] = GlobalToPrivateA2D(a_ptr, tid_y, _ni, kSizeK, idk, _ki); - } - } + bpm[_ni] = GlobalToPrivateB(bgm, _ni, kSizeN, idk); #endif - #endif + } // Performs the accumulation (Cpm += Apm * Bpm) - #if GEMMK == 0 - #pragma unroll - for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { + + #ifdef OUTPUTMN #pragma unroll for (int _mi = 0; _mi < MWI/VWM; _mi += 1) { - const realM aval = apm[_mi]; - #if VWN == 1 - cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni]); - #elif VWN == 2 - cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni].x); - cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi], aval, bpm[_ni].y); - #elif VWN == 4 - cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni].x); - cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi], aval, bpm[_ni].y); - cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi], aval, bpm[_ni].z); - cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi], aval, bpm[_ni].w); - #elif VWN == 8 - cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni].s0); - cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi], aval, bpm[_ni].s1); - cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi], aval, bpm[_ni].s2); - cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi], aval, bpm[_ni].s3); - cpm[(_ni*VWN + 4)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 4)*(MWI/VWM) + _mi], aval, bpm[_ni].s4); - cpm[(_ni*VWN + 5)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 5)*(MWI/VWM) + _mi], aval, bpm[_ni].s5); - cpm[(_ni*VWN + 6)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 6)*(MWI/VWM) + _mi], aval, bpm[_ni].s6); - cpm[(_ni*VWN + 7)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 7)*(MWI/VWM) + _mi], aval, bpm[_ni].s7); - #elif VWN == 16 - cpm[(_ni*VWN + 0 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0 )*(MWI/VWM) + _mi], aval, bpm[_ni].s0); - cpm[(_ni*VWN + 1 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1 )*(MWI/VWM) + _mi], aval, bpm[_ni].s1); - cpm[(_ni*VWN + 2 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 2 )*(MWI/VWM) + _mi], aval, bpm[_ni].s2); - cpm[(_ni*VWN + 3 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 3 )*(MWI/VWM) + _mi], aval, bpm[_ni].s3); - cpm[(_ni*VWN + 4 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 4 )*(MWI/VWM) + _mi], aval, bpm[_ni].s4); - cpm[(_ni*VWN + 5 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 5 )*(MWI/VWM) + _mi], aval, bpm[_ni].s5); - cpm[(_ni*VWN + 6 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 6 )*(MWI/VWM) + _mi], aval, bpm[_ni].s6); - cpm[(_ni*VWN + 7 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 7 )*(MWI/VWM) + _mi], aval, bpm[_ni].s7); - cpm[(_ni*VWN + 8 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 8 )*(MWI/VWM) + _mi], aval, bpm[_ni].s8); - cpm[(_ni*VWN + 9 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 9 )*(MWI/VWM) + _mi], aval, bpm[_ni].s9); - cpm[(_ni*VWN + 10)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 10)*(MWI/VWM) + _mi], aval, bpm[_ni].sA); - cpm[(_ni*VWN + 11)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 11)*(MWI/VWM) + _mi], aval, bpm[_ni].sB); - cpm[(_ni*VWN + 12)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 12)*(MWI/VWM) + _mi], aval, bpm[_ni].sC); - cpm[(_ni*VWN + 13)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 13)*(MWI/VWM) + _mi], aval, bpm[_ni].sD); - cpm[(_ni*VWN + 14)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 14)*(MWI/VWM) + _mi], aval, bpm[_ni].sE); - cpm[(_ni*VWN + 15)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 15)*(MWI/VWM) + _mi], aval, bpm[_ni].sF); - #endif + #pragma unroll + for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { + const realM aval = apm[_mi]; + #if VWM == 1 + // [MWI/VWM, VWM, NWI/VWN, VWN] + cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni], aval, bpm[_ni]); + #elif VWM == 2 + cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni], aval.x, bpm[_ni]); + cpn[(_mi*VWM + 1)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 1)*(NWI/VWN) + _ni], aval.y, bpm[_ni]); + #elif VWM == 4 + cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni], aval.x, bpm[_ni]); + cpn[(_mi*VWM + 1)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 1)*(NWI/VWN) + _ni], aval.y, bpm[_ni]); + cpn[(_mi*VWM + 2)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 2)*(NWI/VWN) + _ni], aval.z, bpm[_ni]); + cpn[(_mi*VWM + 3)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 3)*(NWI/VWN) + _ni], aval.w, bpm[_ni]); + #elif VWM == 8 + cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 0)*(NWI/VWN) + _ni], aval.s0, bpm[_ni]); + cpn[(_mi*VWM + 1)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 1)*(NWI/VWN) + _ni], aval.s1, bpm[_ni]); + cpn[(_mi*VWM + 2)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 2)*(NWI/VWN) + _ni], aval.s2, bpm[_ni]); + cpn[(_mi*VWM + 3)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 3)*(NWI/VWN) + _ni], aval.s3, bpm[_ni]); + cpn[(_mi*VWM + 4)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 4)*(NWI/VWN) + _ni], aval.s4, bpm[_ni]); + cpn[(_mi*VWM + 5)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 5)*(NWI/VWN) + _ni], aval.s5, bpm[_ni]); + cpn[(_mi*VWM + 6)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 6)*(NWI/VWN) + _ni], aval.s6, bpm[_ni]); + cpn[(_mi*VWM + 7)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 7)*(NWI/VWN) + _ni], aval.s7, bpm[_ni]); + #elif VWM == 16 + cpn[(_mi*VWM + 0 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 0 )*(NWI/VWN) + _ni], aval.s0, bpm[_ni]); + cpn[(_mi*VWM + 1 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 1 )*(NWI/VWN) + _ni], aval.s1, bpm[_ni]); + cpn[(_mi*VWM + 2 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 2 )*(NWI/VWN) + _ni], aval.s2, bpm[_ni]); + cpn[(_mi*VWM + 3 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 3 )*(NWI/VWN) + _ni], aval.s3, bpm[_ni]); + cpn[(_mi*VWM + 4 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 4 )*(NWI/VWN) + _ni], aval.s4, bpm[_ni]); + cpn[(_mi*VWM + 5 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 5 )*(NWI/VWN) + _ni], aval.s5, bpm[_ni]); + cpn[(_mi*VWM + 6 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 6 )*(NWI/VWN) + _ni], aval.s6, bpm[_ni]); + cpn[(_mi*VWM + 7 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 7 )*(NWI/VWN) + _ni], aval.s7, bpm[_ni]); + cpn[(_mi*VWM + 8 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 8 )*(NWI/VWN) + _ni], aval.s8, bpm[_ni]); + cpn[(_mi*VWM + 9 )*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 9 )*(NWI/VWN) + _ni], aval.s9, bpm[_ni]); + cpn[(_mi*VWM + 10)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 10)*(NWI/VWN) + _ni], aval.sA, bpm[_ni]); + cpn[(_mi*VWM + 11)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 11)*(NWI/VWN) + _ni], aval.sB, bpm[_ni]); + cpn[(_mi*VWM + 12)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 12)*(NWI/VWN) + _ni], aval.sC, bpm[_ni]); + cpn[(_mi*VWM + 13)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 13)*(NWI/VWN) + _ni], aval.sD, bpm[_ni]); + cpn[(_mi*VWM + 14)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 14)*(NWI/VWN) + _ni], aval.sE, bpm[_ni]); + cpn[(_mi*VWM + 15)*(NWI/VWN) + _ni] = MultiplyAddVectorN(cpn[(_mi*VWM + 15)*(NWI/VWN) + _ni], aval.sF, bpm[_ni]); + #endif + } } - } - #elif GEMMK == 1 - #pragma unroll - for (int _ni = 0; _ni < NWI; _ni += 1) { + #else #pragma unroll - for (int _mi = 0; _mi < MWI/VWM; _mi += 1) { + for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { #pragma unroll - for (int _ki = 0; _ki < KREG/VWN; _ki += 1) { - #if USE_SUBGROUP_SHUFFLING == 1 - const realN aval = clblast_sub_group_shuffle(apm[_ki], _ni); - #else - const realN aval = apm[_ni * (KREG/VWN) + _ki]; - #endif + for (int _mi = 0; _mi < MWI/VWM; _mi += 1) { + const realM aval = apm[_mi]; #if VWN == 1 - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 0) * (MWI/VWM) + _mi], aval); + cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni]); #elif VWN == 2 - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 0) * (MWI/VWM) + _mi], aval.x); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 1) * (MWI/VWM) + _mi], aval.y); + cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni].x); + cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi], aval, bpm[_ni].y); #elif VWN == 4 - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 0) * (MWI/VWM) + _mi], aval.x); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 1) * (MWI/VWM) + _mi], aval.y); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 2) * (MWI/VWM) + _mi], aval.z); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 3) * (MWI/VWM) + _mi], aval.w); + cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni].x); + cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi], aval, bpm[_ni].y); + cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi], aval, bpm[_ni].z); + cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi], aval, bpm[_ni].w); #elif VWN == 8 - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 0) * (MWI/VWM) + _mi], aval.s0); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 1) * (MWI/VWM) + _mi], aval.s1); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 2) * (MWI/VWM) + _mi], aval.s2); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 3) * (MWI/VWM) + _mi], aval.s3); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 4) * (MWI/VWM) + _mi], aval.s4); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 5) * (MWI/VWM) + _mi], aval.s5); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 6) * (MWI/VWM) + _mi], aval.s6); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 7) * (MWI/VWM) + _mi], aval.s7); + cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0)*(MWI/VWM) + _mi], aval, bpm[_ni].s0); + cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1)*(MWI/VWM) + _mi], aval, bpm[_ni].s1); + cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 2)*(MWI/VWM) + _mi], aval, bpm[_ni].s2); + cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 3)*(MWI/VWM) + _mi], aval, bpm[_ni].s3); + cpm[(_ni*VWN + 4)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 4)*(MWI/VWM) + _mi], aval, bpm[_ni].s4); + cpm[(_ni*VWN + 5)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 5)*(MWI/VWM) + _mi], aval, bpm[_ni].s5); + cpm[(_ni*VWN + 6)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 6)*(MWI/VWM) + _mi], aval, bpm[_ni].s6); + cpm[(_ni*VWN + 7)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 7)*(MWI/VWM) + _mi], aval, bpm[_ni].s7); #elif VWN == 16 - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 0 ) * (MWI/VWM) + _mi], aval.s0); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 1 ) * (MWI/VWM) + _mi], aval.s1); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 2 ) * (MWI/VWM) + _mi], aval.s2); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 3 ) * (MWI/VWM) + _mi], aval.s3); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 4 ) * (MWI/VWM) + _mi], aval.s4); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 5 ) * (MWI/VWM) + _mi], aval.s5); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 6 ) * (MWI/VWM) + _mi], aval.s6); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 7 ) * (MWI/VWM) + _mi], aval.s7); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 8 ) * (MWI/VWM) + _mi], aval.s8); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 9 ) * (MWI/VWM) + _mi], aval.s9); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 10) * (MWI/VWM) + _mi], aval.sA); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 11) * (MWI/VWM) + _mi], aval.sB); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 12) * (MWI/VWM) + _mi], aval.sC); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 13) * (MWI/VWM) + _mi], aval.sD); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 14) * (MWI/VWM) + _mi], aval.sE); - cpm[_ni * (MWI/VWM) + _mi] = MultiplyAddVector(cpm[_ni * (MWI/VWM) + _mi], bpm[(VWN * _ki + 15) * (MWI/VWM) + _mi], aval.sF); + cpm[(_ni*VWN + 0 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 0 )*(MWI/VWM) + _mi], aval, bpm[_ni].s0); + cpm[(_ni*VWN + 1 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 1 )*(MWI/VWM) + _mi], aval, bpm[_ni].s1); + cpm[(_ni*VWN + 2 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 2 )*(MWI/VWM) + _mi], aval, bpm[_ni].s2); + cpm[(_ni*VWN + 3 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 3 )*(MWI/VWM) + _mi], aval, bpm[_ni].s3); + cpm[(_ni*VWN + 4 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 4 )*(MWI/VWM) + _mi], aval, bpm[_ni].s4); + cpm[(_ni*VWN + 5 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 5 )*(MWI/VWM) + _mi], aval, bpm[_ni].s5); + cpm[(_ni*VWN + 6 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 6 )*(MWI/VWM) + _mi], aval, bpm[_ni].s6); + cpm[(_ni*VWN + 7 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 7 )*(MWI/VWM) + _mi], aval, bpm[_ni].s7); + cpm[(_ni*VWN + 8 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 8 )*(MWI/VWM) + _mi], aval, bpm[_ni].s8); + cpm[(_ni*VWN + 9 )*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 9 )*(MWI/VWM) + _mi], aval, bpm[_ni].s9); + cpm[(_ni*VWN + 10)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 10)*(MWI/VWM) + _mi], aval, bpm[_ni].sA); + cpm[(_ni*VWN + 11)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 11)*(MWI/VWM) + _mi], aval, bpm[_ni].sB); + cpm[(_ni*VWN + 12)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 12)*(MWI/VWM) + _mi], aval, bpm[_ni].sC); + cpm[(_ni*VWN + 13)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 13)*(MWI/VWM) + _mi], aval, bpm[_ni].sD); + cpm[(_ni*VWN + 14)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 14)*(MWI/VWM) + _mi], aval, bpm[_ni].sE); + cpm[(_ni*VWN + 15)*(MWI/VWM) + _mi] = MultiplyAddVector(cpm[(_ni*VWN + 15)*(MWI/VWM) + _mi], aval, bpm[_ni].sF); #endif } } - } #endif - } } #if SA == 1 || SB == 1 @@ -1065,46 +1064,30 @@ INLINE_FUNC void XgemmBody(const int kSizeM, const int kSizeN, const int kSizeK, #endif #ifdef OUTPUTMN - // Revise to [M, N] - realN cpn; // MWI * NWI - - real* cpn_mxn = (real *)(&cpn); - real* cpm_nxm = (real *)cpm; - - #pragma unroll - for (int _mi = 0; _mi < MWI; _mi += 1) { - - #pragma unroll - for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { #pragma unroll - for (int _nip = 0; _nip < VWN; _nip += 1) { - cpn_mxn[_nip] = cpm_nxm[(_ni*VWN+_nip) * MWI + _mi]; + for (int _mi = 0; _mi < MWI; _mi += 1) { + #pragma unroll + for (int _ni = 0; _ni < NWI/VWN; _ni += 1) { + StoreResultsN((__global realN* )cgm, cpn[_mi * (NWI/VWN) + _ni], + #ifdef BIAS + egm, + #endif + _mi, _ni, kSizeN, alpha, beta); + } } - - StoreResultsN((__global realN* )cgm, cpn, - #ifdef BIAS - egm, - #endif - _mi, _ni, kSizeN, alpha, beta); - } - } #else - // Stores an MWG * NWG tile of results and performs the multiplication with alpha and beta - #if GEMMK == 0 - const int cld = kSizeM; - #elif GEMMK == 1 - const int cld = kSizeN; - #endif - - #pragma unroll - for (int _ni = 0; _ni < NWI; _ni += 1) { - #pragma unroll - for (int _mi = 0; _mi < MWI/VWM; _mi += 1) { - StoreResultsM(cgm, cpm[_ni * (MWI/VWM) + _mi], _mi, _ni, cld, alpha, beta); - } - } + // Stores an MWG * NWG tile of results and performs the multiplication with alpha and beta + const int cld = kSizeM; + + #pragma unroll + for (int _ni = 0; _ni < NWI; _ni += 1) { + #pragma unroll + for (int _mi = 0; _mi < MWI/VWM; _mi += 1) { + StoreResultsM(cgm, cpm[_ni * (MWI/VWM) + _mi], _mi, _ni, cld, alpha, beta); + } + } #endif } @@ -1123,47 +1106,91 @@ void Xgemm(const int kSizeM, const int kSizeN, const int kSizeK, const __global realN* restrict egm, // [N] #endif __global realM* cgm, - const int a_offset, const int b_offset, const int c_offset) { - const real alpha = GetRealArg(arg_alpha); - const real beta = GetRealArg(arg_beta); - - // Adds the offsets (in case of use of a single temporary buffer for A, B, and C) - agm = (const __global realM*)((const __global real*)agm + a_offset); - bgm = (const __global realN*)((const __global real*)bgm + b_offset); - cgm = (__global realM*)((const __global real*)cgm + c_offset); - - // Allocates workgroup-private memory (local memory) - #if SA == 1 - __local realM alm[KWG * MWG/VWM]; - #endif - #if SB == 1 - __local realN blm[KWG * NWG/VWN]; - #endif + const int a_offset, const int b_offset, const int c_offset +) { + const real alpha = GetRealArg(arg_alpha); + const real beta = GetRealArg(arg_beta); + + // Adds the offsets (in case of use of a single temporary buffer for A, B, and C) + agm = (const __global realM*)((const __global real*)agm + a_offset); + bgm = (const __global realN*)((const __global real*)bgm + b_offset); + cgm = (__global realM*)((const __global real*)cgm + c_offset); + + // Allocates workgroup-private memory (local memory) + #if SA == 1 + __local realM alm[KWG * MWG/VWM]; + #endif + #if SB == 1 + __local realN blm[KWG * NWG/VWN]; + #endif + + // Computes the matrix-multiplication and stores the result in global memory + #if SA == 1 && SB == 1 + XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, + #ifdef BIAS + egm, + #endif + cgm, alpha, beta, alm, blm); + #elif SA == 1 + XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, + #ifdef BIAS + egm, + #endif + cgm, alpha, beta, alm); + #elif SB == 1 + XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, + #ifdef BIAS + egm, + #endif + cgm, alpha, beta, blm); + #else + XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, + #ifdef BIAS + egm, + #endif + cgm, alpha, beta); + #endif +} - // Computes the matrix-multiplication and stores the result in global memory - #if SA == 1 && SB == 1 - XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, - #ifdef BIAS - egm, - #endif - cgm, alpha, beta, alm, blm); - #elif SA == 1 - XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, - #ifdef BIAS - egm, - #endif - cgm, alpha, beta, alm); - #elif SB == 1 - XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, - #ifdef BIAS - egm, - #endif - cgm, alpha, beta, blm); - #else - XgemmBody(kSizeM, kSizeN, kSizeK, agm, bgm, - #ifdef BIAS - egm, - #endif - cgm, alpha, beta); - #endif +#if RELAX_WORKGROUP_SIZE == 1 + __kernel +#else + __kernel __attribute__((reqd_work_group_size(MDIMC, NDIMC, 1))) +#endif +void XgemmBatched(const int kSizeM, const int kSizeN, const int kSizeK, + const real_arg arg_alpha, + const real_arg arg_beta, + const __global realM* restrict agm, const int a_one, const int a_two, + const __global realN* restrict bgm, const int b_one, const int b_two, + __global realM* cgm, const int c_one, const int c_two) { + const int batch = get_group_id(2); + const real alpha = GetRealArg(arg_alpha); + const real beta = GetRealArg(arg_beta); + + // Sets the offsets + const int a_offset = batch * a_one * a_two; + const int b_offset = batch * b_one * b_two; + const int c_offset = batch * c_one * c_two; + const __global realM* restrict agm_ = &agm[a_offset / VWM]; + const __global realN* restrict bgm_ = &bgm[b_offset / VWN]; + __global realM* restrict cgm_ = &cgm[c_offset / VWM]; + + // Allocates workgroup-private memory (local memory) + #if SA == 1 + __local realM alm[KWG * MWG/VWM]; + #endif + #if SB == 1 + __local realN blm[KWG * NWG/VWN]; + #endif + + // Computes the matrix-multiplication and stores the result in global memory + #if SA == 1 && SB == 1 + XgemmBody(kSizeM, kSizeN, kSizeK, agm_, bgm_, cgm_, alpha, beta, alm, blm); + #elif SA == 1 + XgemmBody(kSizeM, kSizeN, kSizeK, agm_, bgm_, cgm_, alpha, beta, alm); + #elif SB == 1 + XgemmBody(kSizeM, kSizeN, kSizeK, agm_, bgm_, cgm_, alpha, beta, blm); + #else + XgemmBody(kSizeM, kSizeN, kSizeK, agm_, bgm_, cgm_, alpha, beta); + #endif } diff --git a/source/backend/opencl/execution/cl/opencl_codegen.py b/source/backend/opencl/execution/cl/opencl_codegen.py index 7082e823c..56d497aee 100644 --- a/source/backend/opencl/execution/cl/opencl_codegen.py +++ b/source/backend/opencl/execution/cl/opencl_codegen.py @@ -1,5 +1,6 @@ import os import sys +import re major_py_ver = sys.version_info.major def convert_string_to_hex_list(code_str): @@ -16,76 +17,85 @@ def opencl_codegen(): if not os.path.exists(cl_kernel_dir): print(cl_kernel_dir + " doesn't exist!") -#common.h - common_header_code = "" -#quantized_common.h - quantized_common_header_code = "" -#activation_common.h - activation_common_header_code = "" - for file_name in os.listdir(cl_kernel_dir): - file_path = os.path.join(cl_kernel_dir, file_name) - if file_path[-2:] == ".h" and file_name[:-2] == "quantized_common": - with open(file_path, "r") as f: - quantized_common_header_code += f.read() - elif file_path[-2:] == ".h" and file_name[:-2] == "activation_common": - with open(file_path, "r") as f: - activation_common_header_code += f.read() - opencl_code_maps = {} - for file_name in os.listdir(cl_kernel_dir): - file_path = os.path.join(cl_kernel_dir, file_name) - if file_path[-3:] == ".cl": - with open(file_path, "r") as f: - code_str = "" - for line in f.readlines(): - if "#include " in line: - code_str += common_header_code - code_str += activation_common_header_code - elif "#include " in line: - code_str += common_header_code - code_str += quantized_common_header_code - elif "#include " in line: - code_str += common_header_code - else: - code_str += line - opencl_code_maps[file_name[:-3]] = convert_string_to_hex_list(code_str) + #source model opencl_source_map = "#include \n" opencl_source_map += "#include \n" opencl_source_map += "#include \n" opencl_source_map += "#include \n" + opencl_source_map += "#include \"opencl_source_map.hpp\" \n" opencl_source_map += "namespace MNN { \n" opencl_source_map += "std::mutex gCLMutex;\n" - opencl_source_map += "extern const std::map> OpenCLProgramMap = \n { \n" + + opencl_source_hpp = "#include \n" + opencl_source_hpp += "#include \n" + opencl_source_hpp += "#include \n" + opencl_source_hpp += "#include \n" + opencl_source_hpp += "namespace MNN { \n" - if major_py_ver == 2: - items = opencl_code_maps.iteritems() - else: - items = opencl_code_maps.items() - for file_name, file_source in items: - if file_name[-4:] == "_buf": - opencl_source_map += "#ifndef MNN_OPENCL_BUFFER_CLOSED\n" - if file_name[-13:] == "_subgroup_buf": - opencl_source_map += "#ifdef MNN_SUPPORT_INTEL_SUBGROUP\n" - opencl_source_map += "{\n \"" - opencl_source_map += file_name - opencl_source_map += "\", \n" - opencl_source_map += " { " - for source_hex in file_source: - opencl_source_map += source_hex - opencl_source_map += "," - opencl_source_map += " } " - opencl_source_map += "\n }, \n" - if file_name[-4:] == "_buf": - opencl_source_map += "#endif\n" - if file_name[-13:] == "_subgroup_buf": - opencl_source_map += "#endif\n" - opencl_source_map += " }; \n" - opencl_source_map += "} \n" + opencl_source_map_hpp = "const std::map OpenCLProgramMap = \n { \n" + spaceReg = re.compile(' +') + for file_name_all in os.listdir(cl_kernel_dir): + file_path = os.path.join(cl_kernel_dir, file_name_all) + if file_path[-3:] == ".cl": + with open(file_path, "r") as f: + file_name = file_name_all[:-3] + if file_name[-4:] == "_buf": + opencl_source_map += "#ifndef MNN_OPENCL_BUFFER_CLOSED\n" + opencl_source_hpp += "#ifndef MNN_OPENCL_BUFFER_CLOSED\n" + opencl_source_map_hpp += "#ifndef MNN_OPENCL_BUFFER_CLOSED\n" + if file_name[-13:] == "_subgroup_buf": + opencl_source_map += "#ifdef MNN_SUPPORT_INTEL_SUBGROUP\n" + opencl_source_hpp += "#ifdef MNN_SUPPORT_INTEL_SUBGROUP\n" + opencl_source_map_hpp += "#ifdef MNN_SUPPORT_INTEL_SUBGROUP\n" + opencl_source_hpp += "extern const char* " + file_name + ";\n" + opencl_source_map += "const char* " + file_name + " = \n" + opencl_source_map_hpp += " { \"" + file_name + "\", " + file_name + " },\n" + lines = f.read().split("\n") + for l in lines: + if (len(l) < 1): + continue + if l.find('printf') >= 0: + l = l.replace('\"', '\\\"') + l = l.replace('\\n', '\\\\n') + opencl_source_map += "\""+l+"\"\n" + elif l.find('\\') >= 0: + l = l.replace('\\', '') + l = spaceReg.sub(' ', l) + opencl_source_map += "\""+l+"\"" + else: + l = l + "\\n" + l = l.replace('\t', '') + l = spaceReg.sub(' ', l) + l = l.replace(', ', ',') + l = l.replace(' = ', '=') + l = l.replace(' + ', '+') + l = l.replace(' - ', '-') + l = l.replace(' * ', '*') + l = l.replace(' / ', '/') + l = l.replace(' < ', '<') + l = l.replace(' > ', '>') + opencl_source_map += "\""+l+"\"\n" + opencl_source_map += ";\n" + if file_name[-4:] == "_buf": + opencl_source_map += "#endif\n" + opencl_source_hpp += "#endif\n" + opencl_source_map_hpp += "#endif\n" + if file_name[-13:] == "_subgroup_buf": + opencl_source_map += "#endif\n" + opencl_source_hpp += "#endif\n" + opencl_source_map_hpp += "#endif\n" + opencl_source_map += "}\n" + opencl_source_map_hpp += "};\n" + opencl_source_map_hpp += "}\n" with open(output_path, "w") as w_file: w_file.write(opencl_source_map) + with open("opencl_source_map.hpp", "w") as w_file: + w_file.write(opencl_source_hpp) + w_file.write(opencl_source_map_hpp) print("Generate OpenCL Source done !!! \n") diff --git a/source/backend/opencl/execution/cl/opencl_program.cc b/source/backend/opencl/execution/cl/opencl_program.cc index 7a460a3a0..b72288012 100644 --- a/source/backend/opencl/execution/cl/opencl_program.cc +++ b/source/backend/opencl/execution/cl/opencl_program.cc @@ -2,357 +2,22626 @@ #include #include #include +#include "opencl_source_map.hpp" namespace MNN { std::mutex gCLMutex; -extern const std::map> OpenCLProgramMap = - { -{ - "conv_2d", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x69,0x2c,0x20,0x62,0x61,0x73,0x65,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x23,0x23,0x69,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x23,0x23,0x69,0x20,0x2b,0x20,0x62,0x61,0x73,0x65,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x23,0x23,0x69,0x20,0x3d,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x23,0x23,0x69,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x23,0x23,0x69,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x23,0x23,0x69,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x23,0x23,0x69,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x23,0x23,0x69,0x2c,0x20,0x69,0x6e,0x5f,0x68,0x62,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x3b,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x69,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x69,0x2e,0x78,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x69,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x69,0x2e,0x7a,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x69,0x2e,0x77,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x20,0x20,0x20,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x69,0x2c,0x20,0x6a,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x6a,0x2e,0x78,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x6a,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x6a,0x2e,0x7a,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x23,0x23,0x6a,0x2e,0x77,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x4f,0x50,0x54,0x28,0x69,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x5f,0x73,0x6d,0x23,0x23,0x69,0x5b,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x78,0x5d,0x2e,0x78,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x5f,0x73,0x6d,0x23,0x23,0x69,0x5b,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x78,0x5d,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x5f,0x73,0x6d,0x23,0x23,0x69,0x5b,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x78,0x5d,0x2e,0x7a,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x5f,0x73,0x6d,0x23,0x23,0x69,0x5b,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x78,0x5d,0x2e,0x77,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x23,0x23,0x69,0x29,0x3b,0x20,0x20,0x20,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x55,0x4e,0x49,0x54,0x20,0x34,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x20,0x31,0x35,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x23,0x69,0x66,0x20,0x53,0x45,0x54,0x5f,0x41,0x54,0x54,0x52,0x49,0x42,0x55,0x54,0x45,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x68,0x69,0x6e,0x74,0x28,0x31,0x36,0x2c,0x20,0x31,0x36,0x2c,0x20,0x31,0x29,0x29,0x29,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x31,0x78,0x31,0x5f,0x6d,0x61,0x6c,0x69,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x55,0x46,0x46,0x45,0x52,0x5f,0x49,0x4e,0x50,0x5f,0x46,0x50,0x33,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x62,0x69,0x61,0x73,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x63,0x2f,0x34,0x20,0x77,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x62,0x20,0x68,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x34,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x55,0x46,0x46,0x45,0x52,0x5f,0x49,0x4e,0x50,0x5f,0x46,0x50,0x33,0x32,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x29,0x62,0x69,0x61,0x73,0x5f,0x70,0x74,0x72,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x29,0x62,0x69,0x61,0x73,0x5f,0x70,0x74,0x72,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x3b,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x3b,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x33,0x3b,0x20,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x31,0x36,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0x20,0x2b,0x2b,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x5f,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x55,0x46,0x46,0x45,0x52,0x5f,0x49,0x4e,0x50,0x5f,0x46,0x50,0x33,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x2c,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x29,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x69,0x6e,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x69,0x6e,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x69,0x6e,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x69,0x6e,0x30,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x69,0x6e,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x69,0x6e,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x69,0x6e,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x69,0x6e,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x69,0x6e,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x69,0x6e,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x69,0x6e,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x69,0x6e,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x69,0x6e,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x69,0x6e,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x69,0x6e,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x69,0x6e,0x33,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x77,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x23,0x69,0x66,0x20,0x53,0x45,0x54,0x5f,0x41,0x54,0x54,0x52,0x49,0x42,0x55,0x54,0x45,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x68,0x69,0x6e,0x74,0x28,0x31,0x36,0x2c,0x20,0x31,0x36,0x2c,0x20,0x31,0x29,0x29,0x29,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x31,0x78,0x31,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x34,0x3b,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2a,0x20,0x38,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x53,0x31,0x44,0x31,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x33,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0x20,0x2b,0x2b,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x38,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x38,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x32,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x32,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x33,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x33,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x34,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x34,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x35,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x35,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x36,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x36,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x37,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x37,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x23,0x69,0x66,0x20,0x53,0x45,0x54,0x5f,0x41,0x54,0x54,0x52,0x49,0x42,0x55,0x54,0x45,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x68,0x69,0x6e,0x74,0x28,0x31,0x36,0x2c,0x20,0x31,0x36,0x2c,0x20,0x31,0x29,0x29,0x29,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x31,0x78,0x31,0x5f,0x63,0x38,0x68,0x31,0x77,0x34,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2a,0x20,0x38,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x34,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x35,0x20,0x3d,0x20,0x6f,0x75,0x74,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x36,0x20,0x3d,0x20,0x6f,0x75,0x74,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x37,0x20,0x3d,0x20,0x6f,0x75,0x74,0x34,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x53,0x31,0x44,0x31,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x33,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3d,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x2c,0x20,0x49,0x4e,0x54,0x5f,0x4d,0x49,0x4e,0x2c,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0x20,0x2b,0x2b,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x31,0x36,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x38,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x20,0x2a,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x20,0x2b,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x32,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x32,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x33,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x33,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x34,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x34,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x35,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x35,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x36,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x36,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x37,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x37,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x38,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x38,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x39,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x39,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x61,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x61,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x62,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x62,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x63,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x63,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x64,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x64,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x65,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x65,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x66,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x2e,0x73,0x66,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x34,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x35,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x36,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x37,0x2c,0x20,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x34,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x34,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x35,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x35,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x36,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x36,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x37,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x37,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x34,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x34,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x35,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x35,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x36,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x36,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x37,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x37,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x23,0x69,0x66,0x20,0x53,0x45,0x54,0x5f,0x41,0x54,0x54,0x52,0x49,0x42,0x55,0x54,0x45,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x68,0x69,0x6e,0x74,0x28,0x31,0x36,0x2c,0x20,0x31,0x36,0x2c,0x20,0x31,0x29,0x29,0x29,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x63,0x34,0x68,0x31,0x77,0x34,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x62,0x69,0x61,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3c,0x3c,0x32,0x2c,0x20,0x2d,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x53,0x31,0x44,0x31,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x2c,0x20,0x31,0x2c,0x20,0x2d,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x30,0x2c,0x20,0x28,0x2d,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x20,0x20,0x20,0x3d,0x20,0x6b,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x65,0x6e,0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x20,0x2b,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x30,0x2c,0x20,0x28,0x2d,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x29,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x2d,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x30,0x2c,0x20,0x28,0x2d,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2d,0x20,0x31,0x29,0x20,0x2f,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x65,0x6e,0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x20,0x2b,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x30,0x2c,0x20,0x28,0x2d,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2d,0x20,0x31,0x29,0x20,0x2f,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x29,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x2c,0x20,0x69,0x6e,0x32,0x2c,0x20,0x69,0x6e,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x20,0x2b,0x2b,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x28,0x34,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2b,0x30,0x29,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6b,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x79,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x74,0x61,0x72,0x74,0x3b,0x20,0x69,0x79,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x65,0x6e,0x64,0x3b,0x20,0x69,0x79,0x20,0x2b,0x3d,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x62,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x53,0x31,0x44,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x31,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x32,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x33,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x2b,0x2b,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x31,0x3b,0x20,0x77,0x20,0x3c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x77,0x2b,0x2b,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x69,0x6e,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x32,0x20,0x3d,0x20,0x69,0x6e,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x33,0x2c,0x20,0x77,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x2b,0x2b,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x77,0x20,0x3c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x77,0x2c,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x52,0x45,0x41,0x44,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x49,0x4d,0x41,0x47,0x45,0x28,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x61,0x73,0x65,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x2b,0x2b,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x23,0x69,0x66,0x20,0x53,0x45,0x54,0x5f,0x41,0x54,0x54,0x52,0x49,0x42,0x55,0x54,0x45,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x68,0x69,0x6e,0x74,0x28,0x31,0x36,0x2c,0x20,0x31,0x36,0x2c,0x20,0x31,0x29,0x29,0x29,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x63,0x38,0x68,0x34,0x77,0x31,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x62,0x69,0x61,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x34,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x34,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x35,0x20,0x3d,0x20,0x6f,0x75,0x74,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x36,0x20,0x3d,0x20,0x6f,0x75,0x74,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x37,0x20,0x3d,0x20,0x6f,0x75,0x74,0x34,0x3b,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x2d,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3c,0x3c,0x32,0x2c,0x20,0x2d,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x2c,0x20,0x69,0x6e,0x32,0x2c,0x20,0x69,0x6e,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x20,0x2b,0x2b,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x28,0x34,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2b,0x30,0x29,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x30,0x29,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x79,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x79,0x20,0x3c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0x20,0x69,0x79,0x20,0x2b,0x3d,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x30,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x31,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x32,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x33,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x78,0x20,0x3c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x78,0x20,0x2b,0x3d,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x30,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x69,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x69,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x69,0x78,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x33,0x29,0x29,0x3b,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x30,0x33,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x30,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x37,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x34,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x35,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x36,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x37,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x2b,0x2b,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x34,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x35,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x36,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x53,0x34,0x28,0x37,0x2c,0x20,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x34,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x34,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x35,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x35,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x36,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x36,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x37,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x37,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x34,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x34,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x35,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x35,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x36,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x36,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x37,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x37,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3e,0x3d,0x20,0x34,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x2b,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3e,0x3d,0x20,0x34,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x23,0x69,0x66,0x20,0x53,0x45,0x54,0x5f,0x41,0x54,0x54,0x52,0x49,0x42,0x55,0x54,0x45,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x68,0x69,0x6e,0x74,0x28,0x31,0x36,0x2c,0x20,0x31,0x36,0x2c,0x20,0x31,0x29,0x29,0x29,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x63,0x34,0x68,0x34,0x77,0x31,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x62,0x69,0x61,0x73,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x2d,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3c,0x3c,0x32,0x2c,0x20,0x2d,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x2c,0x20,0x69,0x6e,0x32,0x2c,0x20,0x69,0x6e,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x20,0x2b,0x2b,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0x20,0x7c,0x7c,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x28,0x34,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2b,0x30,0x29,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x30,0x29,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x79,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x79,0x20,0x3c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0x20,0x69,0x79,0x20,0x2b,0x3d,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x30,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x31,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x32,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x33,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x2b,0x20,0x69,0x79,0x20,0x2b,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x2b,0x20,0x69,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x2b,0x20,0x69,0x79,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x78,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x78,0x20,0x3c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x78,0x20,0x2b,0x3d,0x20,0x64,0x69,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x30,0x20,0x3d,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x69,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x69,0x64,0x78,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x69,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x2b,0x20,0x69,0x78,0x20,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x30,0x2c,0x20,0x68,0x33,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x32,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x70,0x74,0x72,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2f,0x32,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x2f,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x34,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x30,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x31,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x32,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x78,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x79,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x30,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x2e,0x77,0x20,0x3d,0x20,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x49,0x6e,0x74,0x34,0x33,0x2e,0x73,0x31,0x20,0x26,0x20,0x4d,0x4f,0x44,0x5f,0x4e,0x55,0x4d,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x30,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x31,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x32,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x33,0x29,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x43,0x34,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x34,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x79,0x5f,0x69,0x64,0x78,0x2b,0x2b,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x41,0x4c,0x43,0x55,0x4c,0x41,0x54,0x45,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x28,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x78,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x79,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3e,0x3d,0x20,0x34,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x79,0x20,0x3d,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x20,0x2b,0x20,0x31,0x29,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, -{ - "deconv_2d", - { 0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x61,0x6c,0x69,0x67,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x2f,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x79,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2f,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x65,0x61,0x6c,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x78,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x65,0x61,0x6c,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x79,0x2c,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x31,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x32,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x33,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x20,0x3d,0x20,0x69,0x63,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x31,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x32,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x20,0x2b,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x33,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x20,0x2b,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x5f,0x79,0x20,0x3d,0x20,0x64,0x65,0x61,0x6c,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x64,0x78,0x5f,0x68,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x79,0x3b,0x20,0x6b,0x5f,0x79,0x20,0x3e,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x5f,0x79,0x20,0x2d,0x3d,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x69,0x64,0x78,0x5f,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x20,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x5f,0x78,0x20,0x3d,0x20,0x64,0x65,0x61,0x6c,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x6b,0x5f,0x78,0x20,0x3e,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x5f,0x78,0x20,0x2d,0x3d,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x5f,0x79,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x6b,0x5f,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x20,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x20,0x5b,0x31,0x2c,0x20,0x20,0x34,0x2a,0x69,0x63,0x43,0x34,0x2c,0x20,0x20,0x6f,0x63,0x43,0x34,0x2a,0x6b,0x68,0x2a,0x6b,0x77,0x2c,0x20,0x20,0x31,0x5d,0x20,0x78,0x69,0x63,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x20,0x20,0x5b,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x2c,0x20,0x30,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x2b,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x31,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x2b,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x32,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x2b,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x33,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x2b,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x72,0x79,0x20,0x3d,0x20,0x28,0x69,0x64,0x78,0x5f,0x68,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x64,0x78,0x5f,0x68,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x69,0x63,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x68,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x72,0x79,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x7a,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x77,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x2b,0x2b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x69,0x64,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x20,0x69,0x64,0x78,0x5f,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x62,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x69,0x64,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x69,0x64,0x78,0x5f,0x68,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x64,0x78,0x5f,0x68,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x20,0x20,0x20,0x3d,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x5f,0x78,0x20,0x3d,0x20,0x64,0x65,0x61,0x6c,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x6b,0x5f,0x78,0x20,0x3e,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x5f,0x78,0x20,0x2d,0x3d,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x5f,0x79,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x6b,0x5f,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x30,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x31,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x32,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x78,0x5f,0x33,0x2c,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x79,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x69,0x63,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x76,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x69,0x6e,0x5f,0x68,0x62,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x79,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x7a,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x30,0x2e,0x77,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x5f,0x77,0x69,0x64,0x74,0x68,0x30,0x2b,0x2b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x55,0x53,0x45,0x5f,0x42,0x55,0x46,0x46,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x69,0x6f,0x68,0x77,0x32,0x6f,0x69,0x68,0x77,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x2c,0x20,0x69,0x6e,0x74,0x20,0x70,0x6c,0x61,0x6e,0x65,0x5f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x2c,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x6f,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x7c,0x7c,0x20,0x6f,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x69,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x6f,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x70,0x6c,0x61,0x6e,0x65,0x5f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6f,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x69,0x63,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x70,0x6c,0x61,0x6e,0x65,0x5f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x70,0x6c,0x61,0x6e,0x65,0x5f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, -{ - "unary", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x67,0x65,0x6c,0x75,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x30,0x2e,0x37,0x39,0x37,0x38,0x38,0x34,0x35,0x38,0x66,0x20,0x2a,0x20,0x28,0x30,0x2e,0x30,0x34,0x34,0x37,0x31,0x35,0x66,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2b,0x20,0x69,0x6e,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x78,0x32,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3e,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x35,0x2e,0x30,0x66,0x20,0x3f,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x31,0x2e,0x30,0x66,0x20,0x3a,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x20,0x3c,0x3d,0x20,0x2d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x35,0x2e,0x30,0x66,0x20,0x3f,0x20,0x2d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x31,0x2e,0x30,0x66,0x20,0x3a,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x20,0x2a,0x20,0x28,0x31,0x33,0x35,0x31,0x33,0x35,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x31,0x37,0x33,0x32,0x35,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x33,0x37,0x38,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x29,0x29,0x29,0x29,0x20,0x2f,0x20,0x28,0x31,0x33,0x35,0x31,0x33,0x35,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x36,0x32,0x33,0x37,0x30,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x33,0x31,0x35,0x30,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x32,0x38,0x2e,0x30,0x66,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x31,0x2e,0x30,0x66,0x20,0x2b,0x20,0x64,0x73,0x74,0x29,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2a,0x20,0x30,0x2e,0x35,0x66,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x75,0x6e,0x61,0x72,0x79,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x62,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x77,0x2c,0x20,0x68,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x20,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x52,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2c,0x20,0x68,0x62,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x49,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2c,0x20,0x68,0x62,0x29,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa, } - }, -#ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "grid_sample_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x7b,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x5a,0x45,0x52,0x4f,0x53,0x20,0x3d,0x20,0x30,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x3d,0x20,0x31,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x52,0x45,0x46,0x4c,0x45,0x43,0x54,0x49,0x4f,0x4e,0x20,0x3d,0x20,0x32,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x4d,0x49,0x4e,0x20,0x3d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x5a,0x45,0x52,0x4f,0x53,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x4d,0x41,0x58,0x20,0x3d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x52,0x45,0x46,0x4c,0x45,0x43,0x54,0x49,0x4f,0x4e,0xa,0x7d,0x3b,0xa,0xa,0x66,0x6c,0x6f,0x61,0x74,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x2c,0x20,0x69,0x6e,0x74,0x20,0x72,0x61,0x6e,0x67,0x65,0x2c,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x61,0x20,0x3d,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x20,0x3d,0x3d,0x20,0x31,0x3f,0x20,0x31,0x2e,0x30,0x66,0x20,0x3a,0x20,0x30,0x2e,0x30,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x62,0x20,0x3d,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x20,0x3d,0x3d,0x20,0x31,0x3f,0x20,0x30,0x2e,0x30,0x66,0x20,0x3a,0x20,0x31,0x2e,0x30,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x28,0x31,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x29,0x20,0x2a,0x20,0x28,0x72,0x61,0x6e,0x67,0x65,0x20,0x2d,0x20,0x61,0x29,0x20,0x2d,0x20,0x62,0x29,0x20,0x2f,0x20,0x32,0x2e,0x30,0x66,0x3b,0xa,0x7d,0xa,0xa,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x69,0x6e,0x74,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x69,0x6e,0x74,0x20,0x76,0x2c,0x20,0x69,0x6e,0x74,0x20,0x6d,0x69,0x6e,0x2c,0x20,0x69,0x6e,0x74,0x20,0x6d,0x61,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x76,0x29,0x20,0x3c,0x20,0x6d,0x69,0x6e,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x76,0x29,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x28,0x76,0x29,0x20,0x3e,0x20,0x6d,0x61,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x76,0x29,0x20,0x3d,0x20,0x6d,0x61,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x3b,0xa,0x7d,0xa,0xa,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x74,0x20,0x68,0x2c,0x20,0x69,0x6e,0x74,0x20,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x75,0x66,0x66,0x65,0x72,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x68,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x68,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x7c,0x7c,0x20,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x77,0x20,0x3e,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x20,0x3d,0x3d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x5a,0x45,0x52,0x4f,0x53,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,0x2e,0x30,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x43,0x6c,0x65,0x61,0x72,0x6c,0x79,0x2c,0x20,0x43,0x4c,0x41,0x4d,0x50,0x20,0x69,0x73,0x20,0x74,0x68,0x65,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x77,0x61,0x79,0x20,0x74,0x6f,0x20,0x67,0x6f,0x20,0x66,0x6f,0x72,0x20,0x47,0x72,0x69,0x64,0x53,0x61,0x6d,0x70,0x6c,0x65,0x50,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x5f,0x42,0x4f,0x52,0x44,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x46,0x6f,0x72,0x20,0x47,0x72,0x69,0x64,0x53,0x61,0x6d,0x70,0x6c,0x65,0x50,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x5f,0x52,0x45,0x46,0x4c,0x45,0x43,0x54,0x49,0x4f,0x4e,0x2c,0x20,0x73,0x69,0x6e,0x63,0x65,0x20,0x77,0x65,0x20,0x68,0x61,0x76,0x65,0x20,0x72,0x65,0x66,0x6c,0x65,0x63,0x74,0x65,0x64,0x20,0x74,0x68,0x65,0x20,0x76,0x61,0x6c,0x75,0x65,0x73,0x20,0x69,0x6e,0x74,0x6f,0x20,0x28,0x2d,0x31,0x2c,0x20,0x31,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x74,0x68,0x65,0x20,0x6c,0x65,0x66,0x74,0x6f,0x76,0x65,0x72,0x20,0x72,0x65,0x66,0x6c,0x65,0x63,0x74,0x69,0x6f,0x6e,0x73,0x20,0x64,0x65,0x67,0x72,0x61,0x64,0x65,0x20,0x74,0x6f,0x20,0x47,0x72,0x69,0x64,0x53,0x61,0x6d,0x70,0x6c,0x65,0x50,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x5f,0x42,0x4f,0x52,0x44,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x68,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x68,0x2c,0x20,0x30,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x77,0x2c,0x20,0x30,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x68,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x29,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6e,0x65,0x61,0x72,0x65,0x73,0x74,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x67,0x72,0x69,0x64,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x72,0x69,0x64,0x20,0x64,0x61,0x74,0x61,0x20,0x66,0x6f,0x72,0x6d,0x61,0x74,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x65,0x64,0x20,0x66,0x72,0x6f,0x6d,0x20,0x6e,0x63,0x68,0x77,0x20,0x74,0x6f,0x20,0x6e,0x63,0x34,0x68,0x77,0x34,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x29,0x20,0x28,0x79,0x31,0x2c,0x79,0x32,0x2c,0x79,0x33,0x2c,0x79,0x34,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x73,0x6c,0x69,0x63,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x31,0x2c,0x79,0x31,0x29,0x2e,0x2e,0x2e,0x28,0x78,0x6e,0x2c,0x79,0x31,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x29,0x20,0x28,0x79,0x31,0x2c,0x79,0x32,0x2c,0x79,0x33,0x2c,0x79,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x3c,0x2d,0x3e,0x20,0x20,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x29,0x20,0x28,0x79,0x35,0x2c,0x79,0x36,0x2c,0x79,0x37,0x2c,0x79,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x31,0x2c,0x79,0x6d,0x29,0x2e,0x2e,0x2e,0x28,0x78,0x6e,0x2c,0x79,0x6d,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x73,0x6c,0x69,0x63,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x29,0x20,0x28,0x79,0x35,0x2c,0x79,0x36,0x2c,0x79,0x37,0x2c,0x79,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0xa,0x20,0x20,0x20,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x6c,0x69,0x63,0x65,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x6c,0x69,0x63,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x6d,0x65,0x61,0x6e,0x73,0x20,0x67,0x69,0x72,0x64,0x20,0x79,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x32,0x20,0x6d,0x65,0x61,0x6e,0x73,0x20,0x67,0x72,0x69,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x72,0x69,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x6c,0x69,0x63,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x73,0x6c,0x69,0x63,0x65,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x67,0x72,0x69,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x67,0x72,0x69,0x64,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x67,0x72,0x69,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x2c,0x20,0x67,0x72,0x69,0x64,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x61,0x72,0x72,0x5b,0x38,0x5d,0x20,0x3d,0x20,0x7b,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x77,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x77,0x7d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x65,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x79,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0x20,0x74,0x6f,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x78,0x2c,0x79,0x20,0x63,0x6f,0x6f,0x72,0x64,0x69,0x6e,0x61,0x74,0x65,0x20,0x72,0x61,0x6e,0x67,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x65,0x74,0x20,0x6e,0x65,0x61,0x72,0x65,0x73,0x74,0x20,0x70,0x6f,0x69,0x6e,0x74,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6e,0x77,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x2b,0x20,0x30,0x2e,0x35,0x66,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6e,0x68,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x2b,0x20,0x30,0x2e,0x35,0x66,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x6e,0x68,0x2c,0x20,0x6e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6c,0x69,0x6e,0x65,0x61,0x72,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x67,0x72,0x69,0x64,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x6c,0x69,0x63,0x65,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x6c,0x69,0x63,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x6d,0x65,0x61,0x6e,0x73,0x20,0x67,0x69,0x72,0x64,0x20,0x79,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x32,0x20,0x6d,0x65,0x61,0x6e,0x73,0x20,0x67,0x72,0x69,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x72,0x69,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x6c,0x69,0x63,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x73,0x6c,0x69,0x63,0x65,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x67,0x72,0x69,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x67,0x72,0x69,0x64,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x67,0x72,0x69,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x2c,0x20,0x67,0x72,0x69,0x64,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x61,0x72,0x72,0x5b,0x38,0x5d,0x20,0x3d,0x20,0x7b,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x77,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x77,0x7d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x65,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x79,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0x20,0x74,0x6f,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x78,0x2c,0x79,0x20,0x63,0x6f,0x6f,0x72,0x64,0x69,0x6e,0x61,0x74,0x65,0x20,0x72,0x61,0x6e,0x67,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x30,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x30,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x31,0x20,0x3d,0x20,0x63,0x65,0x69,0x6c,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x31,0x20,0x3d,0x20,0x63,0x65,0x69,0x6c,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x31,0x20,0x2d,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x79,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x31,0x20,0x2d,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x62,0x69,0x6c,0x69,0x6e,0x65,0x61,0x72,0x20,0x69,0x6e,0x74,0x65,0x72,0x70,0x6f,0x6c,0x61,0x74,0x69,0x6f,0x6e,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x30,0x30,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x30,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x30,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x30,0x31,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x30,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x31,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x31,0x30,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x31,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x30,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x31,0x31,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x31,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x31,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x30,0x30,0x29,0x20,0x20,0x2b,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x66,0x20,0x2d,0x20,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x30,0x31,0x29,0x29,0x20,0x2a,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x79,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x31,0x30,0x29,0x20,0x20,0x2b,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x66,0x20,0x2d,0x20,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x31,0x31,0x29,0x29,0x20,0x2a,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x66,0x2d,0x20,0x79,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa, } - }, -#endif -{ - "interp", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x69,0x6e,0x74,0x65,0x72,0x70,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x73,0x20,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x63,0x61,0x6c,0x65,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x63,0x61,0x6c,0x65,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x76,0x61,0x6c,0x2c,0x20,0x6d,0x69,0x6e,0x5f,0x76,0x61,0x6c,0x2c,0x20,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x29,0x20,0x6d,0x61,0x78,0x28,0x6d,0x69,0x6e,0x28,0x76,0x61,0x6c,0x2c,0x20,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x29,0x2c,0x20,0x6d,0x69,0x6e,0x5f,0x76,0x61,0x6c,0x29,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x20,0x20,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x73,0x63,0x61,0x6c,0x65,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6c,0x66,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x2c,0x20,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x75,0x66,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x20,0x2b,0x20,0x31,0x2c,0x20,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x20,0x20,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x73,0x63,0x61,0x6c,0x65,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6c,0x66,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x2c,0x20,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x75,0x66,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x20,0x2b,0x20,0x31,0x2c,0x20,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x67,0x61,0x70,0x20,0x3d,0x20,0x73,0x63,0x61,0x6c,0x65,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x67,0x61,0x70,0x20,0x20,0x3d,0x20,0x73,0x63,0x61,0x6c,0x65,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2d,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x66,0x6c,0x6f,0x6f,0x72,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x74,0x6f,0x70,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6c,0x66,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6c,0x66,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x74,0x6f,0x70,0x5f,0x72,0x69,0x67,0x68,0x74,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x75,0x66,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6c,0x66,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6c,0x66,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x75,0x66,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x5f,0x72,0x69,0x67,0x68,0x74,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x75,0x66,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x75,0x66,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x74,0x6f,0x70,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x74,0x6f,0x70,0x5f,0x72,0x69,0x67,0x68,0x74,0x20,0x2d,0x20,0x74,0x6f,0x70,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x67,0x61,0x70,0x2c,0x20,0x74,0x6f,0x70,0x5f,0x6c,0x65,0x66,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x5f,0x72,0x69,0x67,0x68,0x74,0x20,0x2d,0x20,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x67,0x61,0x70,0x2c,0x20,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x5f,0x6c,0x65,0x66,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x20,0x2d,0x20,0x74,0x6f,0x70,0x29,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x67,0x61,0x70,0x2c,0x20,0x74,0x6f,0x70,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x77,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x68,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x77,0x72,0x69,0x74,0x65,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x77,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x68,0x29,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa, } - }, -{ - "select", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x5f,0x69,0x6d,0x67,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x69,0x64,0x78,0x2c,0x20,0x69,0x64,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x5f,0x76,0x65,0x63,0x20,0x3d,0x20,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x69,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x64,0x78,0x2c,0x20,0x69,0x64,0x79,0x29,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x53,0x49,0x5a,0x45,0x31,0x5f,0x45,0x55,0x51,0x41,0x4c,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x64,0x78,0x2c,0x20,0x69,0x64,0x79,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x53,0x49,0x5a,0x45,0x32,0x5f,0x45,0x55,0x51,0x41,0x4c,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x64,0x78,0x2c,0x20,0x69,0x64,0x79,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x69,0x6e,0x31,0x2c,0x20,0x69,0x6e,0x30,0x2c,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x5f,0x76,0x65,0x63,0x20,0x3d,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x64,0x78,0x2c,0x20,0x69,0x64,0x79,0x29,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa, } - }, -#ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "range_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x72,0x61,0x6e,0x67,0x65,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x69,0x7a,0x65,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x6e,0x64,0x65,0x78,0x34,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x69,0x6e,0x64,0x65,0x78,0x2c,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x73,0x69,0x7a,0x65,0x2c,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x73,0x69,0x7a,0x65,0x20,0x2a,0x20,0x32,0x2c,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x73,0x69,0x7a,0x65,0x20,0x2a,0x20,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x20,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x20,0x73,0x74,0x65,0x70,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x69,0x6e,0x64,0x65,0x78,0x34,0x29,0x20,0x2a,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x73,0x74,0x65,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x7d,0xa, } - }, -#endif -{ - "performance", - { 0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x44,0x5f,0x56,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x79,0x2c,0x20,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x78,0x2c,0x20,0x79,0x2c,0x20,0x78,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x79,0x2c,0x20,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x78,0x2c,0x20,0x79,0x2c,0x20,0x78,0x29,0x3b,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x36,0x28,0x78,0x2c,0x20,0x79,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x44,0x5f,0x56,0x36,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x36,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x36,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x36,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x36,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x32,0x38,0x28,0x78,0x2c,0x20,0x79,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x36,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x36,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x36,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x36,0x34,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x78,0x2c,0x20,0x79,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x32,0x38,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x32,0x38,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x32,0x38,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x31,0x32,0x38,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x70,0x72,0x65,0x63,0x69,0x73,0x69,0x6f,0x6e,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6d,0x75,0x6c,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6d,0x75,0x6c,0x5f,0x78,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x29,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x5b,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x5d,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x68,0x61,0x6c,0x66,0x34,0x5f,0x70,0x72,0x65,0x63,0x69,0x73,0x69,0x6f,0x6e,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x6c,0x66,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6d,0x75,0x6c,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x68,0x61,0x6c,0x66,0x20,0x6d,0x75,0x6c,0x20,0x20,0x20,0x20,0x3d,0x20,0x28,0x68,0x61,0x6c,0x66,0x29,0x6d,0x75,0x6c,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x68,0x61,0x6c,0x66,0x34,0x20,0x6d,0x75,0x6c,0x5f,0x78,0x20,0x3d,0x20,0x28,0x68,0x61,0x6c,0x66,0x34,0x29,0x28,0x6d,0x75,0x6c,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x68,0x61,0x6c,0x66,0x34,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x20,0x3d,0x20,0x28,0x68,0x61,0x6c,0x66,0x34,0x29,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x4d,0x41,0x44,0x5f,0x56,0x32,0x35,0x36,0x28,0x6d,0x75,0x6c,0x5f,0x78,0x2c,0x20,0x6d,0x75,0x6c,0x5f,0x79,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x74,0x72,0x5b,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x5d,0x20,0x3d,0x20,0x28,0x6d,0x75,0x6c,0x5f,0x79,0x2e,0x53,0x30,0x29,0x20,0x2b,0x20,0x28,0x6d,0x75,0x6c,0x5f,0x79,0x2e,0x53,0x31,0x29,0x20,0x2b,0x20,0x28,0x6d,0x75,0x6c,0x5f,0x79,0x2e,0x53,0x32,0x29,0x20,0x2b,0x20,0x28,0x6d,0x75,0x6c,0x5f,0x79,0x2e,0x53,0x33,0x29,0x3b,0xa,0x7d,0xa, } - }, -{ - "winogradTransformSource2_3_1", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x77,0x69,0x6e,0x6f,0x67,0x72,0x61,0x64,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x53,0x6f,0x75,0x72,0x63,0x65,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x30,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x33,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x58,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x59,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2f,0x2f,0x20,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2a,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x58,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x70,0x6f,0x73,0x2e,0x79,0x2c,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x32,0x20,0x2d,0x20,0x70,0x61,0x64,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x32,0x20,0x2d,0x20,0x70,0x61,0x64,0x59,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x30,0x20,0x3d,0x20,0x2b,0x53,0x30,0x30,0x20,0x2d,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x30,0x20,0x3d,0x20,0x2b,0x53,0x31,0x30,0x20,0x2d,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x30,0x20,0x3d,0x20,0x2b,0x53,0x32,0x30,0x20,0x2d,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x30,0x20,0x3d,0x20,0x2b,0x53,0x33,0x30,0x20,0x2d,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x33,0x20,0x3d,0x20,0x2d,0x53,0x30,0x31,0x20,0x2b,0x20,0x53,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x33,0x20,0x3d,0x20,0x2d,0x53,0x31,0x31,0x20,0x2b,0x20,0x53,0x31,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x33,0x20,0x3d,0x20,0x2d,0x53,0x32,0x31,0x20,0x2b,0x20,0x53,0x32,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x33,0x20,0x3d,0x20,0x2d,0x53,0x33,0x31,0x20,0x2b,0x20,0x53,0x33,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x30,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x30,0x20,0x2d,0x20,0x6d,0x32,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x29,0x2c,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x29,0x2c,0x20,0x2d,0x6d,0x31,0x30,0x20,0x2b,0x20,0x6d,0x33,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x34,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x31,0x20,0x2d,0x20,0x6d,0x32,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x35,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x36,0x29,0x2c,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x37,0x29,0x2c,0x20,0x2d,0x6d,0x31,0x31,0x20,0x2b,0x20,0x6d,0x33,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x38,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x32,0x20,0x2d,0x20,0x6d,0x32,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x39,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x30,0x29,0x2c,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x31,0x29,0x2c,0x20,0x2d,0x6d,0x31,0x32,0x20,0x2b,0x20,0x6d,0x33,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x32,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x33,0x20,0x2d,0x20,0x6d,0x32,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x33,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x34,0x29,0x2c,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x35,0x29,0x2c,0x20,0x2d,0x6d,0x31,0x33,0x20,0x2b,0x20,0x6d,0x33,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, -#ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "gemv_conv1x1_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x69,0x6e,0x64,0x65,0x78,0x30,0x2c,0x20,0x69,0x6e,0x64,0x65,0x78,0x31,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x64,0x65,0x78,0x30,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x64,0x65,0x78,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x61,0x2c,0x20,0x62,0x2c,0x20,0x63,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x61,0x2e,0x73,0x30,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x31,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x30,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x32,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x33,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x31,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x34,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x32,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x35,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x32,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x36,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x33,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x37,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x33,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x61,0x2e,0x73,0x38,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x34,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x39,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x34,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x61,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x35,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x62,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x35,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x63,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x36,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x64,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x36,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x65,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x37,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x66,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x37,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x62,0x2e,0x73,0x30,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x38,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x31,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x38,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x32,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x39,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x33,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x39,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x34,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x61,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x35,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x61,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x36,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x62,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x37,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x62,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x62,0x2e,0x73,0x38,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x63,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x39,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x63,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x61,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x64,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x62,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x64,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x63,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x65,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x64,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x65,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x65,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x66,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x62,0x2e,0x73,0x66,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x66,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x55,0x43,0x48,0x41,0x52,0x38,0x5f,0x54,0x4f,0x5f,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x61,0x2c,0x20,0x63,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x61,0x2e,0x73,0x30,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x30,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x31,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x30,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x32,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x31,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x33,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x31,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x34,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x32,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x35,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x32,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x36,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x33,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x37,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x33,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x61,0x2e,0x73,0x38,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x34,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x39,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x34,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x61,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x35,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x62,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x35,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x63,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x36,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x64,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x36,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x65,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x37,0x20,0x3e,0x3e,0x20,0x34,0x29,0x20,0x2d,0x20,0x38,0x3b,0x20,0x61,0x2e,0x73,0x66,0x20,0x3d,0x20,0x28,0x63,0x2e,0x73,0x37,0x20,0x26,0x20,0x31,0x35,0x29,0x20,0x2d,0x20,0x38,0x3b,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x61,0x2c,0x20,0x62,0x2c,0x20,0x63,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x63,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x62,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x63,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x62,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x63,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x62,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x63,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x62,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x3b,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6d,0x6d,0x5f,0x63,0x6f,0x6e,0x76,0x5f,0x63,0x34,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x63,0x2f,0x34,0x20,0x77,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x62,0x20,0x68,0xa,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x68,0x20,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x33,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x36,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x63,0x61,0x6c,0x65,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2f,0x34,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x34,0x38,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x34,0x38,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x31,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x31,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x32,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6d,0x6d,0x5f,0x63,0x6f,0x6e,0x76,0x5f,0x63,0x32,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x63,0x2f,0x34,0x20,0x77,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x62,0x20,0x68,0xa,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x32,0x29,0x20,0x2f,0x20,0x34,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x28,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x32,0x29,0x25,0x34,0x29,0x3b,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x68,0x20,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x32,0x20,0x2a,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x33,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x32,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x36,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x53,0x63,0x61,0x6c,0x65,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2f,0x34,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x31,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x31,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x32,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6d,0x6d,0x5f,0x63,0x6f,0x6e,0x76,0x5f,0x63,0x31,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x63,0x68,0x61,0x72,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x2a,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x63,0x2f,0x34,0x20,0x77,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x62,0x20,0x68,0xa,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x5b,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2f,0x34,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x25,0x34,0x29,0x3b,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x68,0x20,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x33,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x36,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x53,0x63,0x61,0x6c,0x65,0x20,0x3d,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x5b,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x5d,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2f,0x34,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x38,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x38,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x38,0x5f,0x54,0x4f,0x5f,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x3b,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x38,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x38,0x28,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x38,0x5f,0x54,0x4f,0x5f,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x31,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6d,0x6d,0x5f,0x63,0x6f,0x6e,0x76,0x5f,0x63,0x32,0x5f,0x69,0x6d,0x61,0x67,0x65,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x63,0x2f,0x34,0x20,0x77,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x62,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x62,0x69,0x61,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2f,0x34,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x3b,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x68,0x20,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x53,0x63,0x61,0x6c,0x65,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x76,0x6c,0x6f,0x61,0x64,0x32,0x28,0x30,0x2c,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x2d,0x31,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2f,0x34,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x61,0x73,0x5f,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x61,0x73,0x5f,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6b,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x61,0x73,0x5f,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x61,0x73,0x5f,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6b,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x33,0x32,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x37,0x29,0x20,0x3e,0x3e,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x33,0x32,0x2d,0x31,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2f,0x38,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x38,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x38,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6b,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x33,0x32,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x38,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x6b,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0x20,0x2f,0x2f,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0xa,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x31,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x31,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x32,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x6f,0x75,0x74,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6d,0x6d,0x5f,0x63,0x6f,0x6e,0x76,0x5f,0x63,0x31,0x5f,0x69,0x6d,0x61,0x67,0x65,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x63,0x2f,0x34,0x20,0x77,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x62,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x5b,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2f,0x34,0x29,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x25,0x34,0x29,0x3b,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x68,0x20,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x75,0x6d,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x62,0x61,0x74,0x63,0x68,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x53,0x63,0x61,0x6c,0x65,0x20,0x3d,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x53,0x63,0x61,0x6c,0x65,0x5b,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x64,0x65,0x71,0x75,0x61,0x6e,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x38,0x29,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x2d,0x31,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2f,0x34,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x61,0x73,0x5f,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x31,0x36,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x34,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x61,0x73,0x5f,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x34,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x28,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x20,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0x29,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x33,0x32,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x37,0x29,0x20,0x3e,0x3e,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x33,0x32,0x2d,0x31,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2f,0x38,0x3b,0x20,0x6b,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x38,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x38,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x57,0x49,0x44,0x54,0x48,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x5f,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x20,0x2a,0x20,0x33,0x32,0x20,0x2b,0x20,0x31,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x33,0x32,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x38,0x20,0x3d,0x20,0x6b,0x20,0x2a,0x20,0x38,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x20,0x3d,0x20,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x31,0x36,0x28,0x72,0x65,0x61,0x64,0x5f,0x69,0x6d,0x61,0x67,0x65,0x66,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6b,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x68,0x61,0x72,0x31,0x36,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x55,0x43,0x48,0x41,0x52,0x31,0x36,0x5f,0x54,0x4f,0x5f,0x32,0x43,0x48,0x41,0x52,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x49,0x6e,0x74,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x63,0x68,0x61,0x72,0x57,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x31,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x32,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x32,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x6b,0x38,0x20,0x2a,0x20,0x77,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x34,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x35,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x36,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x3f,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x33,0x20,0x2b,0x20,0x28,0x6b,0x38,0x20,0x2b,0x20,0x37,0x29,0x20,0x2a,0x20,0x77,0x68,0x29,0x20,0x3a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x30,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x30,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x33,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x31,0x2e,0x73,0x30,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x31,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x32,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x33,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x34,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x35,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x36,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x37,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x38,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x39,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x61,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x62,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x63,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x64,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x31,0x2e,0x73,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x4f,0x54,0x31,0x36,0x58,0x31,0x36,0x28,0x69,0x6e,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0x20,0x2f,0x2f,0x55,0x53,0x45,0x5f,0x4c,0x4f,0x57,0x5f,0x42,0x49,0x54,0x5f,0x57,0x45,0x49,0x47,0x48,0x54,0x5f,0x49,0x4e,0x54,0x34,0xa,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x41,0x43,0x54,0x48,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x31,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x31,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x32,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x32,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x56,0x61,0x6c,0x69,0x64,0x42,0x61,0x74,0x63,0x68,0x33,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x30,0x20,0x2b,0x20,0x6d,0x61,0x64,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x53,0x63,0x61,0x6c,0x65,0x2c,0x20,0x73,0x75,0x6d,0x33,0x20,0x2a,0x20,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x33,0x2c,0x20,0x30,0x2c,0x20,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa, } - }, -#endif -{ - "raster", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x5f,0x73,0x65,0x74,0x5f,0x7a,0x65,0x72,0x6f,0x28,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x79,0x2a,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x2b,0x20,0x78,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x28,0x30,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x69,0x6d,0x61,0x67,0x65,0x5f,0x73,0x65,0x74,0x5f,0x7a,0x65,0x72,0x6f,0x28,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x78,0x2c,0x20,0x79,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x78,0x2c,0x20,0x79,0x29,0x2c,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x34,0x29,0x28,0x30,0x29,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x72,0x61,0x73,0x74,0x65,0x72,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x5f,0x64,0x69,0x72,0x65,0x63,0x74,0x28,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x6f,0x6d,0x62,0x69,0x6e,0x65,0x53,0x72,0x63,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x6f,0x6d,0x62,0x69,0x6e,0x65,0x44,0x73,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x30,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x7a,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x64,0x78,0x2c,0x20,0x79,0x2c,0x20,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x69,0x64,0x78,0x20,0x25,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x20,0x3d,0x20,0x69,0x64,0x78,0x20,0x2f,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x64,0x20,0x2a,0x20,0x63,0x6f,0x6d,0x62,0x69,0x6e,0x65,0x53,0x72,0x63,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x7a,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x64,0x20,0x2a,0x20,0x63,0x6f,0x6d,0x62,0x69,0x6e,0x65,0x44,0x73,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x7a,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x5f,0x46,0x4f,0x52,0x4d,0x41,0x54,0x5f,0x4e,0x48,0x57,0x43,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x73,0x72,0x63,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x73,0x72,0x63,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x62,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x20,0x73,0x72,0x63,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x73,0x72,0x63,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x73,0x72,0x63,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x62,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x20,0x73,0x72,0x63,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x63,0x6f,0x6f,0x72,0x64,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x28,0x69,0x6e,0x5f,0x63,0x20,0x2f,0x20,0x34,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x2c,0x20,0x69,0x6e,0x5f,0x62,0x20,0x2a,0x20,0x73,0x72,0x63,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x52,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x63,0x6f,0x6f,0x72,0x64,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x2a,0x29,0x26,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x5b,0x69,0x6e,0x5f,0x63,0x20,0x25,0x20,0x34,0x5d,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x72,0x61,0x73,0x74,0x65,0x72,0x5f,0x69,0x6d,0x61,0x67,0x65,0x28,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x7a,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x79,0x2c,0x20,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x7a,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x7a,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x30,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x31,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x53,0x74,0x72,0x69,0x64,0x65,0x32,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x6e,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x20,0x28,0x28,0x69,0x6e,0x70,0x75,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2b,0x33,0x29,0x2f,0x34,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x28,0x28,0x69,0x6e,0x70,0x75,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2b,0x33,0x29,0x2f,0x34,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x63,0x34,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2f,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x25,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2f,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x25,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x77,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x6e,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x2f,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2b,0x33,0x29,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2b,0x33,0x29,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x63,0x34,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2f,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x25,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2f,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x25,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x77,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x49,0x6e,0x64,0x65,0x78,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x63,0x34,0x2a,0x69,0x6e,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x6e,0x2a,0x69,0x6e,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x5f,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x63,0x34,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x6e,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x5f,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x52,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x30,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x69,0x64,0x78,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x30,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x31,0x29,0x2c,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x49,0x34,0x28,0x6f,0x75,0x74,0x29,0x29,0x3b,0xa,0x7d,0xa, } - }, +const char* conv_2d = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define READ_INPUT_IMAGE(i, base) "" int in_width_value##i = in_width##i + base; "" in_width_value##i = "" select(in_idx + in_width_value##i, -1, (in_width_value##i < 0 || in_width_value##i >= input_shape.y)); "" in##i=RI_F(input,SAMPLER,(int2)(in_width_value##i,in_hb_value));\n" +"#define CALCULATE_OUTPUT(i) "" out##i = mad(in##i.x, weights0, out##i); "" out##i = mad(in##i.y, weights1, out##i); "" out##i = mad(in##i.z, weights2, out##i); "" out##i=mad(in##i.w,weights3,out##i); \n" +"#define CALCULATE_OUTPUT_WEIGHTS4(i, j) "" out##i = mad(in##j.x, weights4, out##i); "" out##i = mad(in##j.y, weights5, out##i); "" out##i = mad(in##j.z, weights6, out##i); "" out##i=mad(in##j.w,weights7,out##i);\n" +"#define CALCULATE_OUTPUT_OPT(i) "" out##i = mad(in_sm##i[local_idx].x, weights0, out##i); "" out##i = mad(in_sm##i[local_idx].y, weights1, out##i); "" out##i = mad(in_sm##i[local_idx].z, weights2, out##i); "" out##i=mad(in_sm##i[local_idx].w,weights3,out##i); \n" +"#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0,__private const int global_size_dim1,\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"#define UNIT 4\n" +"#define MOD_NUM 15\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" #define PADZEROSVEC(k, channel, data0, data1, data2, data3) "" data0 = (k << 2) < channel ? data0 : 0; "" data1 = (k << 2) + 1 < channel ? data1 : 0; "" data2 = (k << 2) + 2 < channel ? data2 : 0; "" data3=(k << 2)+3= 4) {\n" +" WI_F(output,(int2)(output_idx,out_b_h_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,out_b_h_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,out_b_h_idx),out2);\n" +" WI_F(output,(int2)(output_idx+3,out_b_h_idx),out3);\n" +" } else if (remain == 3) {\n" +" WI_F(output,(int2)(output_idx,out_b_h_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,out_b_h_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,out_b_h_idx),out2);\n" +" } else if (remain == 2) {\n" +" WI_F(output,(int2)(output_idx,out_b_h_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,out_b_h_idx),out1);\n" +" } else if (remain == 1) {\n" +" WI_F(output,(int2)(output_idx,out_b_h_idx),out0);\n" +" }\n" +"}\n" +"__kernel\n" +"#if SET_ATTRIBUTE\n" +"__attribute__((work_group_size_hint(16,16,1)))\n" +"#endif\n" +"void conv_2d_1x1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_BUFFER)\n" +" __global const FLOAT *weights,\n" +"#else\n" +" __read_only image2d_t weights,\n" +"#endif\n" +" __read_only image2d_t bias,\n" +" __write_only image2d_t output,\n" +" __private const int2 input_shape,\n" +" __private const int in_channel_block,__private const int2 output_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int output_width_4,\n" +" __private const int out_channel_blocks\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" ,__private const int blockDim\n" +" ,__private const int inChannel\n" +"#endif\n" +") {\n" +" const int output_channel_width_idx=get_global_id(0);\n" +" const int output_batch_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(output_channel_width_idx,output_batch_height_idx);\n" +" const int output_channel_block_idx=output_channel_width_idx/output_width_4;\n" +" const int output_width_block_idx=output_channel_width_idx % output_width_4;\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" int weight_ic_offset=output_channel_block_idx*8;\n" +" int weight_oc_offset=out_channel_blocks*8;\n" +"#else\n" +" int weight_ic_offset=output_channel_block_idx*16;\n" +" int weight_oc_offset=out_channel_blocks*16;\n" +"#endif\n" +" FLOAT4 out0=RI_F(bias,SAMPLER,(int2)(output_channel_block_idx,0));\n" +" FLOAT4 out1=out0;\n" +" FLOAT4 out2=out0;\n" +" FLOAT4 out3=out0;\n" +"#ifdef MNN_CONV_S1D1\n" +" int intput_width_idx0=output_width_block_idx << 2;\n" +" int intput_width_idx1=intput_width_idx0+1;\n" +" int intput_width_idx2=intput_width_idx0+2;\n" +" int intput_width_idx3=intput_width_idx0+3;\n" +"#else\n" +" int intput_width_idx0=mul24(output_width_block_idx,stride_shape.y*4);\n" +" int intput_width_idx1=intput_width_idx0+stride_shape.y;\n" +" int intput_width_idx2=intput_width_idx1+stride_shape.y;\n" +" int intput_width_idx3=intput_width_idx2+stride_shape.y;\n" +" intput_width_idx0=select(intput_width_idx0,INT_MIN,intput_width_idx0 >= input_shape.y);\n" +" intput_width_idx1=select(intput_width_idx1,INT_MIN,intput_width_idx1 >= input_shape.y);\n" +" intput_width_idx2=select(intput_width_idx2,INT_MIN,intput_width_idx2 >= input_shape.y);\n" +" intput_width_idx3=select(intput_width_idx3,INT_MIN,intput_width_idx3 >= input_shape.y);\n" +"#endif\n" +" int batch_index=output_batch_height_idx/output_shape.x;\n" +" int input_height_block_idx=mul24((output_batch_height_idx % output_shape.x),stride_shape.x)+batch_index*input_shape.x;\n" +" FLOAT4 in0;\n" +" FLOAT4 in1;\n" +" FLOAT4 in2;\n" +" FLOAT4 in3;\n" +" FLOAT4 weights0;\n" +" FLOAT4 weights1;\n" +" FLOAT4 weights2;\n" +" FLOAT4 weights3;\n" +" int weight_offset=output_channel_block_idx*in_channel_block*4*4;\n" +" for (int in_channel_block_idx=0; in_channel_block_idx> 4)-8;\n" +" charWeights0.y=(charWeightsInt4.s0 & MOD_NUM)-8;\n" +" charWeights0.z=(charWeightsInt4.s1 >> 4)-8;\n" +" charWeights0.w=(charWeightsInt4.s1 & MOD_NUM)-8;\n" +" charWeights1.x=(charWeightsInt4.s2 >> 4)-8;\n" +" charWeights1.y=(charWeightsInt4.s2 & MOD_NUM)-8;\n" +" charWeights1.z=(charWeightsInt4.s3 >> 4)-8;\n" +" charWeights1.w=(charWeightsInt4.s3 & MOD_NUM)- 8;\n" +" charWeights2.x=(charWeightsInt4.s4 >> 4)-8;\n" +" charWeights2.y=(charWeightsInt4.s4 & MOD_NUM)-8;\n" +" charWeights2.z=(charWeightsInt4.s5 >> 4)-8;\n" +" charWeights2.w=(charWeightsInt4.s5 & MOD_NUM)-8;\n" +" charWeights3.x=(charWeightsInt4.s6 >> 4)-8;\n" +" charWeights3.y=(charWeightsInt4.s6 & MOD_NUM)-8;\n" +" charWeights3.z=(charWeightsInt4.s7 >> 4)-8;\n" +" charWeights3.w=(charWeightsInt4.s7 & MOD_NUM)-8;\n" +" weights0=mad(CONVERT_FLOAT4(charWeights0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeights1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeights2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeights3),scale0,offset0);\n" +"#elif (defined USE_BUFFER)\n" +" weights0=vload4(weights_width_base,weights+weight_offset);\n" +" weights1=vload4(weights_width_base+1,weights+weight_offset);\n" +" weights2=vload4(weights_width_base+2,weights+weight_offset);\n" +" weights3=vload4(weights_width_base+3,weights+weight_offset);\n" +"#else\n" +" weights0=RI_F(weights,SAMPLER,(int2)(weights_width_base+0,output_channel_block_idx));\n" +" weights1=RI_F(weights,SAMPLER,(int2)(weights_width_base+1,output_channel_block_idx));\n" +" weights2=RI_F(weights,SAMPLER,(int2)(weights_width_base+2,output_channel_block_idx));\n" +" weights3=RI_F(weights,SAMPLER,(int2)(weights_width_base+3,output_channel_block_idx));\n" +"#endif\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights0,weights1,weights2,weights3);\n" +" in0=RI_F(input,SAMPLER,(int2)(input_width_base+intput_width_idx0,input_height_block_idx));\n" +" in1=RI_F(input,SAMPLER,(int2)(input_width_base+intput_width_idx1,input_height_block_idx));\n" +" in2=RI_F(input,SAMPLER,(int2)(input_width_base+intput_width_idx2,input_height_block_idx));\n" +" in3=RI_F(input,SAMPLER,(int2)(input_width_base+intput_width_idx3,input_height_block_idx));\n" +" CALCULATE_OUTPUT(0);\n" +" CALCULATE_OUTPUT(1);\n" +" CALCULATE_OUTPUT(2);\n" +" CALCULATE_OUTPUT(3);\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(FLOAT4)0);\n" +" out1=fmax(out1,(FLOAT4)0);\n" +" out2=fmax(out2,(FLOAT4)0);\n" +" out3=fmax(out3,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(FLOAT4)0,(FLOAT4)6);\n" +" out1=clamp(out1,(FLOAT4)0,(FLOAT4)6);\n" +" out2=clamp(out2,(FLOAT4)0,(FLOAT4)6);\n" +" out3=clamp(out3,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" const int out_x_base=mul24(output_channel_block_idx,output_shape.y);\n" +" int out_x_idx=output_width_block_idx << 2;\n" +" const int remain=output_shape.y-out_x_idx;\n" +" int output_idx=out_x_base+out_x_idx;\n" +" if (remain >= 4) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out2);\n" +" WI_F(output,(int2)(output_idx+3,output_batch_height_idx),out3);\n" +" } else if (remain == 3) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out2);\n" +" } else if (remain == 2) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" } else if (remain == 1) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" }\n" +"}\n" +"__kernel\n" +"#if SET_ATTRIBUTE\n" +"__attribute__((work_group_size_hint(16,16,1)))\n" +"#endif\n" +"void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_BUFFER)\n" +" __global const FLOAT *weights,\n" +"#else\n" +" __read_only image2d_t weights,\n" +"#endif\n" +" __read_only image2d_t bias,\n" +" __write_only image2d_t output,\n" +" __private const int2 input_shape,\n" +" __private const int in_channel_block,__private const int2 output_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int output_width_4,\n" +" __private const int out_channel_blocks\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" ,__private const int blockDim\n" +" ,__private const int inChannel\n" +"#endif\n" +") {\n" +" const int output_channel_width_idx=get_global_id(0);\n" +" const int output_batch_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(output_channel_width_idx,output_batch_height_idx);\n" +" const int output_channel_block_idx=output_channel_width_idx/output_width_4;\n" +" const int output_width_block_idx=output_channel_width_idx % output_width_4;\n" +" const int output_channel_idx=output_channel_block_idx << 1;\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" int weight_ic_offset=output_channel_block_idx*16;\n" +" int weight_oc_offset=out_channel_blocks*8;\n" +"#else\n" +" int weight_ic_offset=output_channel_block_idx*32;\n" +" int weight_oc_offset=out_channel_blocks*16;\n" +"#endif\n" +" FLOAT4 out0=RI_F(bias,SAMPLER,(int2)(output_channel_idx,0));\n" +" FLOAT4 out1=out0;\n" +" FLOAT4 out2=out0;\n" +" FLOAT4 out3=out0;\n" +" \n" +" FLOAT4 out4=RI_F(bias,SAMPLER,(int2)(output_channel_idx+1,0));\n" +" FLOAT4 out5=out4;\n" +" FLOAT4 out6=out4;\n" +" FLOAT4 out7=out4;\n" +"#ifdef MNN_CONV_S1D1\n" +" int intput_width_idx0=output_width_block_idx << 2;\n" +" int intput_width_idx1=intput_width_idx0+1;\n" +" int intput_width_idx2=intput_width_idx0+2;\n" +" int intput_width_idx3=intput_width_idx0+3;\n" +"#else\n" +" int intput_width_idx0=mul24(output_width_block_idx,stride_shape.y*4);\n" +" int intput_width_idx1=intput_width_idx0+stride_shape.y;\n" +" int intput_width_idx2=intput_width_idx1+stride_shape.y;\n" +" int intput_width_idx3=intput_width_idx2+stride_shape.y;\n" +" intput_width_idx0=select(intput_width_idx0,INT_MIN,intput_width_idx0 >= input_shape.y);\n" +" intput_width_idx1=select(intput_width_idx1,INT_MIN,intput_width_idx1 >= input_shape.y);\n" +" intput_width_idx2=select(intput_width_idx2,INT_MIN,intput_width_idx2 >= input_shape.y);\n" +" intput_width_idx3=select(intput_width_idx3,INT_MIN,intput_width_idx3 >= input_shape.y);\n" +"#endif\n" +" int batch_index=output_batch_height_idx/output_shape.x;\n" +" int input_height_block_idx=mul24((output_batch_height_idx % output_shape.x),stride_shape.x)+batch_index*input_shape.x;\n" +" FLOAT4 in0;\n" +" FLOAT4 in1;\n" +" FLOAT4 in2;\n" +" FLOAT4 in3;\n" +" FLOAT4 weights0;\n" +" FLOAT4 weights1;\n" +" FLOAT4 weights2;\n" +" FLOAT4 weights3;\n" +" FLOAT4 weights4;\n" +" FLOAT4 weights5;\n" +" FLOAT4 weights6;\n" +" FLOAT4 weights7;\n" +" int weight_offset=output_channel_idx*in_channel_block*4*4;\n" +" int weight_offset1=weight_offset+in_channel_block*4*4;\n" +" for (int in_channel_block_idx=0; in_channel_block_idx> 4)-8;\n" +" charWeights0.y=(charWeightsInt4.s0 & MOD_NUM)-8;\n" +" charWeights0.z=(charWeightsInt4.s1 >> 4)-8;\n" +" charWeights0.w=(charWeightsInt4.s1 & MOD_NUM)-8;\n" +" charWeights1.x=(charWeightsInt4.s2 >> 4)-8;\n" +" charWeights1.y=(charWeightsInt4.s2 & MOD_NUM)-8;\n" +" charWeights1.z=(charWeightsInt4.s3 >> 4)-8;\n" +" charWeights1.w=(charWeightsInt4.s3 & MOD_NUM)-8;\n" +" charWeights2.x=(charWeightsInt4.s4 >> 4)-8;\n" +" charWeights2.y=(charWeightsInt4.s4 & MOD_NUM)-8;\n" +" charWeights2.z=(charWeightsInt4.s5 >> 4)-8;\n" +" charWeights2.w=(charWeightsInt4.s5 & MOD_NUM)-8;\n" +" charWeights3.x=(charWeightsInt4.s6 >> 4)-8;\n" +" charWeights3.y=(charWeightsInt4.s6 & MOD_NUM)-8;\n" +" charWeights3.z=(charWeightsInt4.s7 >> 4)-8;\n" +" charWeights3.w=(charWeightsInt4.s7 & MOD_NUM)-8;\n" +" charWeights4.x=(charWeightsInt4.s8 >> 4)-8;\n" +" charWeights4.y=(charWeightsInt4.s8 & MOD_NUM)-8;\n" +" charWeights4.z=(charWeightsInt4.s9 >> 4)-8;\n" +" charWeights4.w=(charWeightsInt4.s9 & MOD_NUM)-8;\n" +" charWeights5.x=(charWeightsInt4.sa >> 4)-8;\n" +" charWeights5.y=(charWeightsInt4.sa & MOD_NUM)-8;\n" +" charWeights5.z=(charWeightsInt4.sb >> 4)-8;\n" +" charWeights5.w=(charWeightsInt4.sb & MOD_NUM)-8;\n" +" charWeights6.x=(charWeightsInt4.sc >> 4)-8;\n" +" charWeights6.y=(charWeightsInt4.sc & MOD_NUM)-8;\n" +" charWeights6.z=(charWeightsInt4.sd >> 4)-8;\n" +" charWeights6.w=(charWeightsInt4.sd & MOD_NUM)-8;\n" +" charWeights7.x=(charWeightsInt4.se >> 4)-8;\n" +" charWeights7.y=(charWeightsInt4.se & MOD_NUM)-8;\n" +" charWeights7.z=(charWeightsInt4.sf >> 4)-8;\n" +" charWeights7.w=(charWeightsInt4.sf & MOD_NUM)-8;\n" +" weights0=mad(CONVERT_FLOAT4(charWeights0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeights1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeights2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeights3),scale0,offset0);\n" +" weights4=mad(CONVERT_FLOAT4(charWeights4),scale1,offset1);\n" +" weights5=mad(CONVERT_FLOAT4(charWeights5),scale1,offset1);\n" +" weights6=mad(CONVERT_FLOAT4(charWeights6),scale1,offset1);\n" +" weights7=mad(CONVERT_FLOAT4(charWeights7),scale1,offset1);\n" +"#elif (defined USE_BUFFER)\n" +" weights0=vload4(weights_width_base,weights+weight_offset);\n" +" weights1=vload4(weights_width_base+1,weights+weight_offset);\n" +" weights2=vload4(weights_width_base+2,weights+weight_offset);\n" +" weights3=vload4(weights_width_base+3,weights+weight_offset);\n" +" weights4=vload4(weights_width_base,weights+weight_offset1);\n" +" weights5=vload4(weights_width_base+1,weights+weight_offset1);\n" +" weights6=vload4(weights_width_base+2,weights+weight_offset1);\n" +" weights7=vload4(weights_width_base+3,weights+weight_offset1);\n" +"#else\n" +" weights0=RI_F(weights,SAMPLER,(int2)(weights_width_base+0,output_channel_idx));\n" +" weights1=RI_F(weights,SAMPLER,(int2)(weights_width_base+1,output_channel_idx));\n" +" weights2=RI_F(weights,SAMPLER,(int2)(weights_width_base+2,output_channel_idx));\n" +" weights3=RI_F(weights,SAMPLER,(int2)(weights_width_base+3,output_channel_idx));\n" +" \n" +" weights4=RI_F(weights,SAMPLER,(int2)(weights_width_base+0,output_channel_idx+1));\n" +" weights5=RI_F(weights,SAMPLER,(int2)(weights_width_base+1,output_channel_idx+1));\n" +" weights6=RI_F(weights,SAMPLER,(int2)(weights_width_base+2,output_channel_idx+1));\n" +" weights7=RI_F(weights,SAMPLER,(int2)(weights_width_base+3,output_channel_idx+1));\n" +"#endif\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights0,weights1,weights2,weights3);\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights4,weights5,weights6,weights7);\n" +" CALCULATE_OUTPUT(0);\n" +" CALCULATE_OUTPUT(1);\n" +" CALCULATE_OUTPUT(2);\n" +" CALCULATE_OUTPUT(3);\n" +" \n" +" CALCULATE_OUTPUT_WEIGHTS4(4,0);\n" +" CALCULATE_OUTPUT_WEIGHTS4(5,1);\n" +" CALCULATE_OUTPUT_WEIGHTS4(6,2);\n" +" CALCULATE_OUTPUT_WEIGHTS4(7,3);\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(FLOAT4)0);\n" +" out1=fmax(out1,(FLOAT4)0);\n" +" out2=fmax(out2,(FLOAT4)0);\n" +" out3=fmax(out3,(FLOAT4)0);\n" +" out4=fmax(out4,(FLOAT4)0);\n" +" out5=fmax(out5,(FLOAT4)0);\n" +" out6=fmax(out6,(FLOAT4)0);\n" +" out7=fmax(out7,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(FLOAT4)0,(FLOAT4)6);\n" +" out1=clamp(out1,(FLOAT4)0,(FLOAT4)6);\n" +" out2=clamp(out2,(FLOAT4)0,(FLOAT4)6);\n" +" out3=clamp(out3,(FLOAT4)0,(FLOAT4)6);\n" +" out4=clamp(out4,(FLOAT4)0,(FLOAT4)6);\n" +" out5=clamp(out5,(FLOAT4)0,(FLOAT4)6);\n" +" out6=clamp(out6,(FLOAT4)0,(FLOAT4)6);\n" +" out7=clamp(out7,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" const int out_x_base=mul24(output_channel_idx,output_shape.y);\n" +" int out_x_idx=output_width_block_idx << 2;\n" +" const int remain=output_shape.y-out_x_idx;\n" +" int output_idx=out_x_base+out_x_idx;\n" +" if (remain >= 4) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out2);\n" +" WI_F(output,(int2)(output_idx+3,output_batch_height_idx),out3);\n" +" } else if (remain == 3) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out2);\n" +" } else if (remain == 2) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" } else if (remain == 1) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" }\n" +" \n" +" if(output_channel_idx+1 >= out_channel_blocks)\n" +" return;\n" +" output_idx += output_shape.y;\n" +" if (remain >= 4) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out4);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out5);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out6);\n" +" WI_F(output,(int2)(output_idx+3,output_batch_height_idx),out7);\n" +" } else if (remain == 3) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out4);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out5);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out6);\n" +" } else if (remain == 2) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out4);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out5);\n" +" } else if (remain == 1) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out4);\n" +" }\n" +"}\n" +"__kernel\n" +"#if SET_ATTRIBUTE\n" +"__attribute__((work_group_size_hint(16,16,1)))\n" +"#endif\n" +"void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS __read_only image2d_t input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_BUFFER)\n" +" __global const FLOAT *weights,\n" +"#else\n" +" __read_only image2d_t weights,\n" +"#endif\n" +"#ifdef BIAS\n" +" __read_only image2d_t bias,\n" +"#endif\n" +" __write_only image2d_t output,\n" +" __private const int2 input_shape,\n" +" __private const int in_channel_block_length,\n" +" __private const int2 output_shape,\n" +" __private const int2 weights_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 padding_shape,\n" +" __private const int2 dilation_shape,\n" +" __private const int out_width_blocks,\n" +" __private const int out_channel_blocks,\n" +" __private const int out_height_blocks\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" ,__private const int blockDim\n" +" ,__private const int inChannel\n" +"#endif\n" +") {\n" +" const int output_channel_width_idx=get_global_id(0);\n" +" const int output_batch_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(output_channel_width_idx,output_batch_height_idx);\n" +" const int out_channel_block_idx=output_channel_width_idx/out_width_blocks;\n" +" const int out_height_block_idx=output_channel_width_idx % out_width_blocks;\n" +"#ifdef BIAS\n" +" FLOAT4 out0=RI_F(bias,SAMPLER,(int2)(out_channel_block_idx,0));\n" +"#else\n" +" FLOAT4 out0=(FLOAT4)0;\n" +"#endif\n" +" FLOAT4 out1=out0;\n" +" FLOAT4 out2=out0;\n" +" FLOAT4 out3=out0;\n" +" int in_width0=mad24(out_height_block_idx,stride_shape.y<<2,-padding_shape.y);\n" +" int in_width1=in_width0+stride_shape.y;\n" +" int in_width2=in_width0+stride_shape.y*2;\n" +" int in_width3=in_width0+stride_shape.y*3;\n" +" \n" +"#ifdef MNN_CONV_S1D1\n" +" const int height_start=mad24((output_batch_height_idx % output_shape.x),1,-padding_shape.x);\n" +" const int kh_start=select(0,(-height_start),height_start<0);\n" +" int in_height_start=kh_start+height_start;\n" +" int in_height_end=min(weights_shape.x+height_start,input_shape.x);\n" +" const int batch_idx=mul24((output_batch_height_idx/output_shape.x),input_shape.x);\n" +" const int weights_h_idx=mul24(out_channel_block_idx,mul24(weights_shape.y,weights_shape.x))+mul24(select(0,(-height_start),height_start<0),weights_shape.y);\n" +"#else\n" +" const int height_start=mad24((output_batch_height_idx % output_shape.x),stride_shape.x,-padding_shape.x);\n" +" const int kh_start=select(0,(-height_start+dilation_shape.x-1)/dilation_shape.x,height_start<0);\n" +" int in_height_start=mad24(kh_start,dilation_shape.x,height_start);\n" +" int in_height_end=min(mad24(weights_shape.x,dilation_shape.x,height_start),input_shape.x);\n" +" const int batch_idx=mul24((output_batch_height_idx/output_shape.x),input_shape.x);\n" +" const int weights_h_idx=mul24(out_channel_block_idx,mul24(weights_shape.y,weights_shape.x))+mul24(select(0,(-height_start+dilation_shape.x-1)/dilation_shape.x,height_start<0),weights_shape.y);\n" +"#endif\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER)\n" +" const int weight_oc_offset=out_channel_blocks*weights_shape.x*weights_shape.y*4;\n" +"#endif\n" +" FLOAT4 in0,in1,in2,in3;\n" +" FLOAT4 weights0,weights1,weights2,weights3;\n" +" for (int in_channel_block_idx=0; in_channel_block_idx> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weights0=mad(CONVERT_FLOAT4(charWeight0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeight1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeight2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeight3),scale0,offset0);\n" +" weight_offset += 4;\n" +"#elif (defined USE_BUFFER)\n" +" weights0=vload4(0,weights+weight_offset);\n" +" weights1=vload4(0,weights+weight_offset+weight_oc_offset);\n" +" weights2=vload4(0,weights+weight_offset+weight_oc_offset*2);\n" +" weights3=vload4(0,weights+weight_offset+weight_oc_offset*3);\n" +" weight_offset += 4;\n" +"#else\n" +" weights0=RI_F(weights,SAMPLER,(int2)(weights_x_idx+0,weights_y_idx));\n" +" weights1=RI_F(weights,SAMPLER,(int2)(weights_x_idx+1,weights_y_idx));\n" +" weights2=RI_F(weights,SAMPLER,(int2)(weights_x_idx+2,weights_y_idx));\n" +" weights3=RI_F(weights,SAMPLER,(int2)(weights_x_idx+3,weights_y_idx++));\n" +"#endif\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights0,weights1,weights2,weights3);\n" +" CALCULATE_OUTPUT(0);\n" +" CALCULATE_OUTPUT(1);\n" +" CALCULATE_OUTPUT(2);\n" +" CALCULATE_OUTPUT(3);\n" +" }\n" +" for (int w=1; w> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weights0=mad(CONVERT_FLOAT4(charWeight0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeight1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeight2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeight3),scale0,offset0);\n" +" weight_offset += 4;\n" +"#elif (defined USE_BUFFER)\n" +" weights0=vload4(0,weights+weight_offset);\n" +" weights1=vload4(0,weights+weight_offset+weight_oc_offset);\n" +" weights2=vload4(0,weights+weight_offset+weight_oc_offset*2);\n" +" weights3=vload4(0,weights+weight_offset+weight_oc_offset*3);\n" +" weight_offset += 4;\n" +"#else\n" +" weights0=RI_F(weights,SAMPLER,(int2)(weights_x_idx+0,weights_y_idx));\n" +" weights1=RI_F(weights,SAMPLER,(int2)(weights_x_idx+1,weights_y_idx));\n" +" weights2=RI_F(weights,SAMPLER,(int2)(weights_x_idx+2,weights_y_idx));\n" +" weights3=RI_F(weights,SAMPLER,(int2)(weights_x_idx+3,weights_y_idx++));\n" +"#endif\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights0,weights1,weights2,weights3);\n" +" CALCULATE_OUTPUT(0);\n" +" CALCULATE_OUTPUT(1);\n" +" CALCULATE_OUTPUT(2);\n" +" CALCULATE_OUTPUT(3);\n" +" }\n" +"#else\n" +" for (int w=0; w> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weights0=mad(CONVERT_FLOAT4(charWeight0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeight1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeight2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeight3),scale0,offset0);\n" +" weight_offset += 4;\n" +"#elif (defined USE_BUFFER)\n" +" weights0=vload4(0,weights+weight_offset);\n" +" weights1=vload4(0,weights+weight_offset+weight_oc_offset);\n" +" weights2=vload4(0,weights+weight_offset+weight_oc_offset*2);\n" +" weights3=vload4(0,weights+weight_offset+weight_oc_offset*3);\n" +" weight_offset += 4;\n" +"#else\n" +" weights0=RI_F(weights,SAMPLER,(int2)(weights_x_idx+0,weights_y_idx)); \n" +" weights1=RI_F(weights,SAMPLER,(int2)(weights_x_idx+1,weights_y_idx)); \n" +" weights2=RI_F(weights,SAMPLER,(int2)(weights_x_idx+2,weights_y_idx)); \n" +" weights3=RI_F(weights,SAMPLER,(int2)(weights_x_idx+3,weights_y_idx++));\n" +"#endif\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights0,weights1,weights2,weights3);\n" +" CALCULATE_OUTPUT(0);\n" +" CALCULATE_OUTPUT(1);\n" +" CALCULATE_OUTPUT(2);\n" +" CALCULATE_OUTPUT(3);\n" +" }\n" +"#endif\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(FLOAT4)0);\n" +" out1=fmax(out1,(FLOAT4)0);\n" +" out2=fmax(out2,(FLOAT4)0);\n" +" out3=fmax(out3,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(FLOAT4)0,(FLOAT4)6);\n" +" out1=clamp(out1,(FLOAT4)0,(FLOAT4)6);\n" +" out2=clamp(out2,(FLOAT4)0,(FLOAT4)6);\n" +" out3=clamp(out3,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" const int out_x_base=mul24(out_channel_block_idx,output_shape.y);\n" +" int out_x_idx=out_height_block_idx << 2;\n" +" const int remain=output_shape.y-out_x_idx;\n" +" int output_idx=out_x_base+out_x_idx;\n" +" if (remain >= 4) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out2);\n" +" WI_F(output,(int2)(output_idx+3,output_batch_height_idx),out3);\n" +" } else if (remain == 3) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" WI_F(output,(int2)(output_idx+2,output_batch_height_idx),out2);\n" +" } else if (remain == 2) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" WI_F(output,(int2)(output_idx+1,output_batch_height_idx),out1);\n" +" } else if (remain == 1) {\n" +" WI_F(output,(int2)(output_idx,output_batch_height_idx),out0);\n" +" }\n" +"}\n" +"__kernel\n" +"#if SET_ATTRIBUTE\n" +"__attribute__((work_group_size_hint(16,16,1)))\n" +"#endif\n" +"void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_BUFFER)\n" +" __global const FLOAT *weights,\n" +"#else\n" +" __read_only image2d_t weights,\n" +"#endif\n" +"#ifdef BIAS\n" +" __read_only image2d_t bias,\n" +"#endif\n" +" __write_only image2d_t output,\n" +" __private const int2 input_shape,\n" +" __private const int in_channel_block_length,\n" +" __private const int2 output_shape,\n" +" __private const int2 weights_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 padding_shape,\n" +" __private const int2 dilation_shape,\n" +" __private const int out_width_blocks,\n" +" __private const int out_channel_blocks,\n" +" __private const int out_height_blocks\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" ,__private const int blockDim\n" +" ,__private const int inChannel\n" +"#endif\n" +") {\n" +" const int output_channel_width_idx=get_global_id(0);\n" +" const int output_batch_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(output_channel_width_idx,output_batch_height_idx);\n" +" const int out_channel_block_idx=(output_channel_width_idx/out_width_blocks) << 1;\n" +" const int out_width_block_idx=output_channel_width_idx % out_width_blocks;\n" +" const int out_height_block_idx=(output_batch_height_idx % out_height_blocks);\n" +" const int out_batch_block_idx=output_batch_height_idx/out_height_blocks;\n" +"#ifdef BIAS\n" +" FLOAT4 out0=RI_F(bias,SAMPLER,(int2)(out_channel_block_idx,0));\n" +" FLOAT4 out4=RI_F(bias,SAMPLER,(int2)(out_channel_block_idx+1,0));\n" +"#else\n" +" FLOAT4 out0=(FLOAT4)0;\n" +" FLOAT4 out4=(FLOAT4)0;\n" +"#endif\n" +" FLOAT4 out1=out0;\n" +" FLOAT4 out2=out0;\n" +" FLOAT4 out3=out0;\n" +" FLOAT4 out5=out4;\n" +" FLOAT4 out6=out4;\n" +" FLOAT4 out7=out4;\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER)\n" +" const int weight_oc_offset=weights_shape.x*weights_shape.y*4;\n" +" const int weight_ic_offset=out_channel_blocks*weight_oc_offset;\n" +"#endif\n" +" int in_width0=mad24(out_width_block_idx,stride_shape.y,-padding_shape.y);\n" +" int in_height0=mad24(out_height_block_idx,stride_shape.x<<2,-padding_shape.x);\n" +" int in_height1=in_height0+stride_shape.x;\n" +" int in_height2=in_height1+stride_shape.x;\n" +" int in_height3=in_height2+stride_shape.x;\n" +" int weight_size=mul24(weights_shape.y,weights_shape.x);\n" +" \n" +" const int weights_h_idx=mul24(out_channel_block_idx,weight_size);\n" +" const int batch_idx=mul24(out_batch_block_idx,input_shape.x);\n" +" \n" +" FLOAT4 in0,in1,in2,in3;\n" +" FLOAT4 weights0,weights1,weights2,weights3,weights4,weights5,weights6,weights7;\n" +" for (int in_channel_block_idx=0; in_channel_block_idx= input_shape.x));\n" +" int h1=select(in_height1+iy+batch_idx,-1,(in_height1+iy<0 || in_height1+iy >= input_shape.x));\n" +" int h2=select(in_height2+iy+batch_idx,-1,(in_height2+iy<0 || in_height2+iy >= input_shape.x));\n" +" int h3=select(in_height3+iy+batch_idx,-1,(in_height3+iy<0 || in_height3+iy >= input_shape.x));\n" +" for (int ix=0; ix= input_shape.y));\n" +" \n" +" in0=RI_F(input,SAMPLER,(int2)(w0,h0));\n" +" in1=RI_F(input,SAMPLER,(int2)(w0,h1));\n" +" in2=RI_F(input,SAMPLER,(int2)(w0,h2));\n" +" in3=RI_F(input,SAMPLER,(int2)(w0,h3));\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,kernel_ptr+weight_offset);\n" +" char4 charWeight1=vload4(0,kernel_ptr+weight_offset+weight_ic_offset);\n" +" char4 charWeight2=vload4(0,kernel_ptr+weight_offset+weight_ic_offset*2);\n" +" char4 charWeight3=vload4(0,kernel_ptr+weight_offset+weight_ic_offset*3);\n" +" weights0=mad(CONVERT_FLOAT4(charWeight0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeight1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeight2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeight3),scale0,offset0);\n" +" charWeight0=vload4(0,kernel_ptr+weight_offset+weight_oc_offset);\n" +" charWeight1=vload4(0,kernel_ptr+weight_offset+weight_oc_offset+weight_ic_offset);\n" +" charWeight2=vload4(0,kernel_ptr+weight_offset+weight_oc_offset+weight_ic_offset*2);\n" +" charWeight3=vload4(0,kernel_ptr+weight_offset+weight_oc_offset+weight_ic_offset*3);\n" +" weights4=mad(CONVERT_FLOAT4(charWeight0),scale1,offset1);\n" +" weights5=mad(CONVERT_FLOAT4(charWeight1),scale1,offset1);\n" +" weights6=mad(CONVERT_FLOAT4(charWeight2),scale1,offset1);\n" +" weights7=mad(CONVERT_FLOAT4(charWeight3),scale1,offset1);\n" +" weight_offset += 4;\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" uchar2 charWeightInt40=vload2(0,kernel_ptr+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,kernel_ptr+weight_offset/2+weight_ic_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,kernel_ptr+weight_offset/2+weight_ic_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,kernel_ptr+weight_offset/2+weight_ic_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)- 8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weights0=mad(CONVERT_FLOAT4(charWeight0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeight1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeight2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeight3),scale0,offset0);\n" +" charWeightInt40=vload2(0,kernel_ptr+weight_offset/2+weight_oc_offset/2);\n" +" charWeightInt41=vload2(0,kernel_ptr+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2);\n" +" charWeightInt42=vload2(0,kernel_ptr+weight_offset/2+weight_oc_offset/2+weight_ic_offset*2/2);\n" +" charWeightInt43=vload2(0,kernel_ptr+weight_offset/2+weight_oc_offset/2+weight_ic_offset*3/2);\n" +" charWeight0=(char4)(0,0,0,0);\n" +" charWeight1=(char4)(0,0,0,0);\n" +" charWeight2=(char4)(0,0,0,0);\n" +" charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)- 8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)- 8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weights4=mad(CONVERT_FLOAT4(charWeight0),scale1,offset1);\n" +" weights5=mad(CONVERT_FLOAT4(charWeight1),scale1,offset1);\n" +" weights6=mad(CONVERT_FLOAT4(charWeight2),scale1,offset1);\n" +" weights7=mad(CONVERT_FLOAT4(charWeight3),scale1,offset1);\n" +" weight_offset += 4;\n" +"#elif (defined USE_BUFFER)\n" +" weights0=vload4(0,weights+weight_offset);\n" +" weights1=vload4(0,weights+weight_offset+weight_ic_offset);\n" +" weights2=vload4(0,weights+weight_offset+weight_ic_offset*2);\n" +" weights3=vload4(0,weights+weight_offset+weight_ic_offset*3);\n" +" weights4=vload4(0,weights+weight_offset+weight_oc_offset);\n" +" weights5=vload4(0,weights+weight_offset+weight_ic_offset+weight_oc_offset);\n" +" weights6=vload4(0,weights+weight_offset+weight_ic_offset*2+weight_oc_offset);\n" +" weights7=vload4(0,weights+weight_offset+weight_ic_offset*3+weight_oc_offset);\n" +" weight_offset += 4;\n" +"#else\n" +" weights0=RI_F(weights,SAMPLER,(int2)(weights_x_idx+0,weights_y_idx));\n" +" weights1=RI_F(weights,SAMPLER,(int2)(weights_x_idx+1,weights_y_idx));\n" +" weights2=RI_F(weights,SAMPLER,(int2)(weights_x_idx+2,weights_y_idx));\n" +" weights3=RI_F(weights,SAMPLER,(int2)(weights_x_idx+3,weights_y_idx));\n" +" weights4=RI_F(weights,SAMPLER,(int2)(weights_x_idx+0,weight_size+weights_y_idx));\n" +" weights5=RI_F(weights,SAMPLER,(int2)(weights_x_idx+1,weight_size+weights_y_idx));\n" +" weights6=RI_F(weights,SAMPLER,(int2)(weights_x_idx+2,weight_size+weights_y_idx));\n" +" weights7=RI_F(weights,SAMPLER,(int2)(weights_x_idx+3,weight_size+weights_y_idx++));\n" +"#endif\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights0,weights1,weights2,weights3);\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights4,weights5,weights6,weights7);\n" +" \n" +" CALCULATE_OUTPUT(0);\n" +" CALCULATE_OUTPUT(1);\n" +" CALCULATE_OUTPUT(2);\n" +" CALCULATE_OUTPUT(3);\n" +" CALCULATE_OUTPUT_WEIGHTS4(4,0);\n" +" CALCULATE_OUTPUT_WEIGHTS4(5,1);\n" +" CALCULATE_OUTPUT_WEIGHTS4(6,2);\n" +" CALCULATE_OUTPUT_WEIGHTS4(7,3);\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(FLOAT4)0);\n" +" out1=fmax(out1,(FLOAT4)0);\n" +" out2=fmax(out2,(FLOAT4)0);\n" +" out3=fmax(out3,(FLOAT4)0);\n" +" out4=fmax(out4,(FLOAT4)0);\n" +" out5=fmax(out5,(FLOAT4)0);\n" +" out6=fmax(out6,(FLOAT4)0);\n" +" out7=fmax(out7,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(FLOAT4)0,(FLOAT4)6);\n" +" out1=clamp(out1,(FLOAT4)0,(FLOAT4)6);\n" +" out2=clamp(out2,(FLOAT4)0,(FLOAT4)6);\n" +" out3=clamp(out3,(FLOAT4)0,(FLOAT4)6);\n" +" out4=clamp(out4,(FLOAT4)0,(FLOAT4)6);\n" +" out5=clamp(out5,(FLOAT4)0,(FLOAT4)6);\n" +" out6=clamp(out6,(FLOAT4)0,(FLOAT4)6);\n" +" out7=clamp(out7,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" const int out_x_base=mul24(out_channel_block_idx,output_shape.y);\n" +" const int out_y_base=mul24(out_batch_block_idx,output_shape.x);\n" +" int out_x_idx=out_width_block_idx;\n" +" int out_y_idx=out_height_block_idx << 2;\n" +" const int remain_y=output_shape.x-out_y_idx;\n" +" int output_idx=out_x_base+out_x_idx;\n" +" int output_idy=out_y_base+out_y_idx;\n" +" \n" +" if(remain_y >= 4){\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out1);\n" +" WI_F(output,(int2)(output_idx,output_idy+2),out2);\n" +" WI_F(output,(int2)(output_idx,output_idy+3),out3);\n" +" }else if(remain_y == 3){\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out1);\n" +" WI_F(output,(int2)(output_idx,output_idy+2),out2);\n" +" }else if(remain_y == 2){\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out1);\n" +" }else if(remain_y == 1){\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" }\n" +" \n" +" if(out_channel_block_idx+1 >= out_channel_blocks) {\n" +" return;\n" +" }\n" +" output_idx += output_shape.y;\n" +" if(remain_y >= 4){\n" +" WI_F(output,(int2)(output_idx,output_idy),out4);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out5);\n" +" WI_F(output,(int2)(output_idx,output_idy+2),out6);\n" +" WI_F(output,(int2)(output_idx,output_idy+3),out7);\n" +" }else if(remain_y == 3){\n" +" WI_F(output,(int2)(output_idx,output_idy),out4);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out5);\n" +" WI_F(output,(int2)(output_idx,output_idy+2),out6);\n" +" }else if(remain_y == 2){\n" +" WI_F(output,(int2)(output_idx,output_idy),out4);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out5);\n" +" }else if(remain_y == 1){\n" +" WI_F(output,(int2)(output_idx,output_idy),out4);\n" +" }\n" +"}\n" +"__kernel\n" +"#if SET_ATTRIBUTE\n" +"__attribute__((work_group_size_hint(16,16,1)))\n" +"#endif\n" +"void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *kernel_ptr,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_BUFFER)\n" +" __global const FLOAT *weights,\n" +"#else\n" +" __read_only image2d_t weights,\n" +"#endif\n" +"#ifdef BIAS\n" +" __read_only image2d_t bias,\n" +"#endif\n" +" __write_only image2d_t output,\n" +" __private const int2 input_shape,\n" +" __private const int in_channel_block_length,\n" +" __private const int2 output_shape,\n" +" __private const int2 weights_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 padding_shape,\n" +" __private const int2 dilation_shape,\n" +" __private const int out_width_blocks,\n" +" __private const int out_channel_blocks,\n" +" __private const int out_height_blocks\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" ,__private const int blockDim\n" +" ,__private const int inChannel\n" +"#endif\n" +") {\n" +" const int output_channel_width_idx=get_global_id(0);\n" +" const int output_batch_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(output_channel_width_idx,output_batch_height_idx);\n" +" const int out_channel_block_idx=output_channel_width_idx/out_width_blocks;\n" +" const int out_width_block_idx=output_channel_width_idx % out_width_blocks;\n" +" const int out_height_block_idx=(output_batch_height_idx % out_height_blocks);\n" +" const int out_batch_block_idx=output_batch_height_idx/out_height_blocks;\n" +"#ifdef BIAS\n" +" FLOAT4 out0=RI_F(bias,SAMPLER,(int2)(out_channel_block_idx,0));\n" +"#else\n" +" FLOAT4 out0=(FLOAT4)0;\n" +"#endif\n" +" FLOAT4 out1=out0;\n" +" FLOAT4 out2=out0;\n" +" FLOAT4 out3=out0;\n" +" int in_width0=mad24(out_width_block_idx,stride_shape.y,-padding_shape.y);\n" +" int in_height0=mad24(out_height_block_idx,stride_shape.x<<2,-padding_shape.x);\n" +" int in_height1=in_height0+stride_shape.x;\n" +" int in_height2=in_height1+stride_shape.x;\n" +" int in_height3=in_height2+stride_shape.x;\n" +" int weight_size=mul24(weights_shape.y,weights_shape.x);\n" +" \n" +" const int weights_h_idx=mul24(out_channel_block_idx,weight_size);\n" +" const int batch_idx=mul24(out_batch_block_idx,input_shape.x);\n" +" \n" +" FLOAT4 in0,in1,in2,in3;\n" +" FLOAT4 weights0,weights1,weights2,weights3;\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4) || (defined USE_BUFFER)\n" +" const int weight_oc_offset=out_channel_blocks*weights_shape.x*weights_shape.y*4;\n" +"#endif\n" +" for (int in_channel_block_idx=0; in_channel_block_idx= input_shape.x));\n" +" int h1=select(in_height1+iy+batch_idx,-1,(in_height1+iy<0 || in_height1+iy >= input_shape.x));\n" +" int h2=select(in_height2+iy+batch_idx,-1,(in_height2+iy<0 || in_height2+iy >= input_shape.x));\n" +" int h3=select(in_height3+iy+batch_idx,-1,(in_height3+iy<0 || in_height3+iy >= input_shape.x));\n" +" for (int ix=0; ix= input_shape.y));\n" +" \n" +" in0=RI_F(input,SAMPLER,(int2)(w0,h0));\n" +" in1=RI_F(input,SAMPLER,(int2)(w0,h1));\n" +" in2=RI_F(input,SAMPLER,(int2)(w0,h2));\n" +" in3=RI_F(input,SAMPLER,(int2)(w0,h3));\n" +" \n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,kernel_ptr+weight_offset);\n" +" char4 charWeight1=vload4(0,kernel_ptr+weight_offset+weight_oc_offset);\n" +" char4 charWeight2=vload4(0,kernel_ptr+weight_offset+weight_oc_offset*2);\n" +" char4 charWeight3=vload4(0,kernel_ptr+weight_offset+weight_oc_offset*3);\n" +" weights0=mad(CONVERT_FLOAT4(charWeight0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeight1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeight2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeight3),scale0,offset0);\n" +" weight_offset += 4;\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" uchar2 charWeightInt40=vload2(0,kernel_ptr+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,kernel_ptr+weight_offset/2+weight_oc_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,kernel_ptr+weight_offset/2+weight_oc_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,kernel_ptr+weight_offset/2+weight_oc_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weights0=mad(CONVERT_FLOAT4(charWeight0),scale0,offset0);\n" +" weights1=mad(CONVERT_FLOAT4(charWeight1),scale0,offset0);\n" +" weights2=mad(CONVERT_FLOAT4(charWeight2),scale0,offset0);\n" +" weights3=mad(CONVERT_FLOAT4(charWeight3),scale0,offset0);\n" +" weight_offset += 4;\n" +"#elif (defined USE_BUFFER)\n" +" weights0=vload4(0,weights+weight_offset);\n" +" weights1=vload4(0,weights+weight_offset+weight_oc_offset);\n" +" weights2=vload4(0,weights+weight_offset+weight_oc_offset*2);\n" +" weights3=vload4(0,weights+weight_offset+weight_oc_offset*3);\n" +" weight_offset += 4;\n" +"#else\n" +" weights0=RI_F(weights,SAMPLER,(int2)(weights_x_idx+0,weights_y_idx));\n" +" weights1=RI_F(weights,SAMPLER,(int2)(weights_x_idx+1,weights_y_idx));\n" +" weights2=RI_F(weights,SAMPLER,(int2)(weights_x_idx+2,weights_y_idx));\n" +" weights3=RI_F(weights,SAMPLER,(int2)(weights_x_idx+3,weights_y_idx++));\n" +"#endif\n" +" PADZEROSVEC(in_channel_block_idx,inChannel,weights0,weights1,weights2,weights3);\n" +" CALCULATE_OUTPUT(0);\n" +" CALCULATE_OUTPUT(1);\n" +" CALCULATE_OUTPUT(2);\n" +" CALCULATE_OUTPUT(3);\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(FLOAT4)0);\n" +" out1=fmax(out1,(FLOAT4)0);\n" +" out2=fmax(out2,(FLOAT4)0);\n" +" out3=fmax(out3,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(FLOAT4)0,(FLOAT4)6);\n" +" out1=clamp(out1,(FLOAT4)0,(FLOAT4)6);\n" +" out2=clamp(out2,(FLOAT4)0,(FLOAT4)6);\n" +" out3=clamp(out3,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" const int out_x_base=mul24(out_channel_block_idx,output_shape.y);\n" +" const int out_y_base=mul24(out_batch_block_idx,output_shape.x);\n" +" int out_x_idx=out_width_block_idx;\n" +" int out_y_idx=out_height_block_idx << 2;\n" +" const int remain_y=output_shape.x-out_y_idx;\n" +" int output_idx=out_x_base+out_x_idx;\n" +" int output_idy=out_y_base+out_y_idx;\n" +" if(remain_y >= 4){\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out1);\n" +" WI_F(output,(int2)(output_idx,output_idy+2),out2);\n" +" WI_F(output,(int2)(output_idx,output_idy+3),out3);\n" +" }else if(remain_y == 3){\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out1);\n" +" WI_F(output,(int2)(output_idx,output_idy+2),out2);\n" +" }else if(remain_y == 2){\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" WI_F(output,(int2)(output_idx,output_idy+1),out1);\n" +" }else{\n" +" WI_F(output,(int2)(output_idx,output_idy),out0);\n" +" }\n" +"}\n" +; +const char* deconv_2d = +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void deconv_2d(GLOBAL_SIZE_3_DIMS\n" +" #ifdef USE_BUFFER\n" +" __global FLOAT* input,\n" +" __global FLOAT* weights,\n" +" #ifdef BIAS\n" +" __global FLOAT* bias,\n" +" #endif\n" +" __global FLOAT* output,\n" +" #else\n" +" __read_only image2d_t input,\n" +" __read_only image2d_t weights,\n" +" #ifdef BIAS\n" +" __read_only image2d_t bias,\n" +" #endif\n" +" __write_only image2d_t output,\n" +" #endif\n" +" __private const int2 input_shape,\n" +" __private const int2 output_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 align_shape,\n" +" __private const int2 padding_shape,\n" +" __private const int2 kernel_shape,\n" +" __private const int kernel_size,\n" +" __private const int in_channel_blocks,__private const int out_channel_blocks) {\n" +" const int out_channel_blocks_idx=get_global_id(0);\n" +" const int out_w_idx=get_global_id(1);\n" +" const int out_batch_height_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(out_channel_blocks_idx,out_w_idx,out_batch_height_idx);\n" +"#ifdef BIAS\n" +" #ifdef USE_BUFFER\n" +" FLOAT4 out0=vload4(out_channel_blocks_idx,bias);\n" +" #else\n" +" FLOAT4 out0=RI_F(bias,SAMPLER,(int2)(out_channel_blocks_idx,0));\n" +" #endif\n" +"#else\n" +" FLOAT4 out0=(FLOAT4)0;\n" +"#endif\n" +" const int out_b_idx=out_batch_height_idx/output_shape.x;\n" +" const int out_h_idx=out_batch_height_idx % output_shape.x;\n" +" \n" +" int kernel_start_x=max(0,(out_w_idx+align_shape.y)/stride_shape.y);\n" +" int kernel_start_y=max(0,(out_h_idx+align_shape.x)/stride_shape.x);\n" +" int deal_kernel_width=kernel_shape.y-mad24(kernel_start_x,stride_shape.y,padding_shape.y)+out_w_idx-1;\n" +" int deal_kernel_height=kernel_shape.x-mad24(kernel_start_y,stride_shape.x,padding_shape.x)+out_h_idx-1;\n" +" \n" +" \n" +" int kernel_x_0,kernel_x_1,kernel_x_2,kernel_x_3,kernel_y;\n" +" FLOAT4 in0;\n" +" FLOAT4 weights0,weights1,weights2,weights3;\n" +" for (int ic=0; ic= 0; k_y -= stride_shape.x,idx_h++) {\n" +" #ifdef USE_BUFFER\n" +" int in_width0=kernel_start_x;\n" +" for (int k_x=deal_kernel_width; k_x >= 0; k_x -= stride_shape.y) {\n" +" kernel_y=mad24(k_y,kernel_shape.y,k_x);\n" +" kernel_y=mad24(out_channel_blocks_idx,kernel_size,kernel_y);\n" +" //weights NC4HW4 [1,4*icC4,ocC4*kh*kw,1] xic4\n" +" //index: [0,kernel_x_0,kernel_y,0]\n" +" weights0=vload4(kernel_x_0*(out_channel_blocks*kernel_shape.x*kernel_shape.y)+kernel_y,weights);\n" +" weights1=vload4(kernel_x_1*(out_channel_blocks*kernel_shape.x*kernel_shape.y)+kernel_y,weights);\n" +" weights2=vload4(kernel_x_2*(out_channel_blocks*kernel_shape.x*kernel_shape.y)+kernel_y,weights);\n" +" weights3=vload4(kernel_x_3*(out_channel_blocks*kernel_shape.x*kernel_shape.y)+kernel_y,weights);\n" +" bool outBoundry=(idx_h<0 || idx_h >= input_shape.x || kernel_start_x<0 || in_width0 >= input_shape.y);\n" +" int inp_offset=(((out_b_idx*in_channel_blocks+ic)*input_shape.x+idx_h)*input_shape.y+in_width0)*4;\n" +" in0=outBoundry ? (FLOAT4)0 : vload4(0,input+inp_offset);\n" +" out0=mad(in0.x,weights0,out0);\n" +" out0=mad(in0.y,weights1,out0);\n" +" out0=mad(in0.z,weights2,out0);\n" +" out0=mad(in0.w,weights3,out0);\n" +" in_width0++;\n" +" }\n" +" #else\n" +" int in_idy=mad24(out_b_idx,input_shape.x,idx_h);\n" +" int in_hb_value=select(in_idy,-1,idx_h<0 || idx_h >= input_shape.x);\n" +" int in_width0=kernel_start_x;\n" +" for (int k_x=deal_kernel_width; k_x >= 0; k_x -= stride_shape.y) {\n" +" kernel_y=mad24(k_y,kernel_shape.y,k_x);\n" +" kernel_y=mad24(out_channel_blocks_idx,kernel_size,kernel_y);\n" +" weights0=RI_F(weights,SAMPLER,(int2)(kernel_x_0,kernel_y));\n" +" weights1=RI_F(weights,SAMPLER,(int2)(kernel_x_1,kernel_y));\n" +" weights2=RI_F(weights,SAMPLER,(int2)(kernel_x_2,kernel_y));\n" +" weights3=RI_F(weights,SAMPLER,(int2)(kernel_x_3,kernel_y));\n" +" int in_idx=mul24(ic,input_shape.y);\n" +" int in_width_value0 = in_width0; "" in_width_value0 = "" select(in_idx + in_width_value0, -1, (in_width_value0 < 0 || in_width_value0 >= input_shape.y)); "" in0=RI_F(input,SAMPLER,(int2)(in_width_value0,in_hb_value));\n" +" out0=mad(in0.x,weights0,out0);\n" +" out0=mad(in0.y,weights1,out0);\n" +" out0=mad(in0.z,weights2,out0);\n" +" out0=mad(in0.w,weights3,out0);\n" +" in_width0++;\n" +" }\n" +" #endif\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +"#ifdef USE_BUFFER\n" +" const int out_offset=(((out_b_idx*out_channel_blocks+out_channel_blocks_idx)*output_shape.x+out_h_idx)*output_shape.y+out_w_idx)*4;\n" +" vstore4(out0,0,output+out_offset);\n" +"#else\n" +" int out_image_width_idx=mad24(out_channel_blocks_idx,output_shape.y,out_w_idx);\n" +" WI_F(output,(int2)(out_image_width_idx,out_batch_height_idx),out0);\n" +"#endif\n" +"}\n" +"__kernel void iohw2oihw(__global const float* input_ptr,__global float* output_ptr,int plane_number,int input_channel,int output_channel) {\n" +" const int ic_index=get_global_id(0),oc_index=get_global_id(1);\n" +" if (ic_index >= input_channel || oc_index >= output_channel) {\n" +" return;\n" +" }\n" +" const int input_offset=(ic_index*output_channel+oc_index)*plane_number;\n" +" const int output_offset=(oc_index*input_channel+ic_index)*plane_number;\n" +" for (int i=0; i= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"inline float4 gelu(float4 in){\n" +" float4 value=0.79788458f*(0.044715f*in*in*in+in);\n" +" float4 x2=value*value;\n" +" float4 dst=value>(float4)5.0f ? (float4)1.0f : (value <= -(float4)5.0f ? -(float4)1.0f :\n" +" (value*(135135.0f+x2*(17325.0f+x2*(378.0f+x2))))/(135135.0f+x2*(62370.0f+x2*(3150.0f+x2*28.0f))));\n" +" return (1.0f+dst)*in*0.5f;\n" +"}\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void unary(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,__write_only image2d_t output) {\n" +" const int channel_block_idx=get_global_id(0);\n" +" const int w=get_global_id(1);\n" +" const int hb=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(channel_block_idx,w,hb);\n" +" const int width=global_size_dim1;\n" +" const int pos=mad24(channel_block_idx,width,w);\n" +" float4 in=convert_float4(RI_DATA(input,SAMPLER,(int2)(pos,hb)));\n" +" OUTPUT_TYPE_I4 out=CONVERT_OUTPUT_I4(OPERATOR);\n" +" \n" +" WI_DATA(output,(int2)(pos,hb),out);\n" +"}\n" +; +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* grid_sample_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"enum BorderMode {\n" +" BorderMode_ZEROS=0,\n" +" BorderMode_CLAMP=1,\n" +" BorderMode_REFLECTION=2,\n" +" BorderMode_MIN=BorderMode_ZEROS,\n" +" BorderMode_MAX=BorderMode_REFLECTION\n" +"};\n" +"float getPosition(float x,int range,int alignCorners){\n" +" float a=alignCorners == 1? 1.0f : 0.0f;\n" +" float b=alignCorners == 1? 0.0f : 1.0f;\n" +" return ((1.0f+x)*(range-a)-b)/2.0f;\n" +"}\n" +"static int CLAMP(int v,int min,int max) {\n" +" if ((v)max) {\n" +" (v)=max;\n" +" }\n" +" return v;\n" +"}\n" +"COMPUTE_FLOAT4 sample(int h,int w,\n" +" const int offset_base,\n" +" __global const FLOAT *buffer,\n" +" int height,int width,\n" +" enum BorderMode paddingMode){\n" +" if (h<0 || h >= height || w<0 || w >= width) {\n" +" if(paddingMode == BorderMode_ZEROS)\n" +" {\n" +" return 0.0f;\n" +" }\n" +" // Clearly,CLAMP is the right way to go for GridSamplePaddingMode_BORDER\n" +" // For GridSamplePaddingMode_REFLECTION,since we have reflected the values into (-1,1),\n" +" // the leftover reflections degrade to GridSamplePaddingMode_BORDER\n" +" h=CLAMP(h,0,height-1);\n" +" w=CLAMP(w,0,width-1);\n" +" }\n" +" int offset=(offset_base+h)*width+w;\n" +" return CONVERT_COMPUTE_FLOAT4(vload4(offset,buffer));\n" +"}\n" +"__kernel void nearest_buf(GLOBAL_SIZE_3_DIMS __global const FLOAT* input,\n" +" __global const FLOAT* grid,\n" +" __global FLOAT* output,\n" +" __private const int input_height,\n" +" __private const int input_width,\n" +" __private const int output_height,\n" +" __private const int output_width,\n" +" __private const int channelBlocks,\n" +" __private const enum BorderMode paddingMode,\n" +" __private const int alignCorners){\n" +" \n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" const int output_batch_idx=output_batch_height_block_idx/output_height;\n" +" const int output_height_idx=output_batch_height_block_idx % output_height;\n" +" // grid data format has been converted from nchw to nc4hw4\n" +" /* \n" +" (x1,x1,x1,x1) (y1,y2,y3,y4) \n" +" . . \n" +" . . slice\n" +" (x1,y1)...(xn,y1) . . \n" +" . . (xn,xn,xn,xn) (y1,y2,y3,y4)\n" +" . . <-> ---------------------------\n" +" . . (x1,x1,x1,x1) (y5,y6,y7,y8)\n" +" (x1,ym)...(xn,ym) . .\n" +" . . slice\n" +" . .\n" +" (xn,xn,xn,xn) (y5,y6,y7,y8)\n" +" ---------------------------\n" +" */\n" +" const int slice=output_height_idx/4;\n" +" const int slice_blocks=(output_height+3)/4;\n" +" // output_width_block_idx means gird y offset,2 means grid width\n" +" const int grid_offset=((output_batch_idx*slice_blocks+slice)*output_width+output_width_block_idx)*2;\n" +" COMPUTE_FLOAT4 grid_x=CONVERT_COMPUTE_FLOAT4(vload4(grid_offset,grid));\n" +" COMPUTE_FLOAT4 grid_y=CONVERT_COMPUTE_FLOAT4(vload4(grid_offset+1,grid));\n" +" const float arr[8]={grid_x.x,grid_y.x,grid_x.y,grid_y.y,grid_x.z,grid_y.z,grid_x.w,grid_y.w};\n" +" \n" +" // get grid x,y\n" +" const int arr_offset=output_height_idx % 4;\n" +" const float x=arr[2*arr_offset];\n" +" const float y=arr[2*arr_offset+1];\n" +" // convert grid x,y to input x,y coordinate range\n" +" float in_grid_x=getPosition(x,input_width,alignCorners);\n" +" float in_grid_y=getPosition(y,input_height,alignCorners);\n" +" // get nearest point\n" +" int nw=floor(in_grid_x+0.5f);\n" +" int nh=floor(in_grid_y+0.5f);\n" +" const int inp_offset_base=(output_batch_idx*channelBlocks+output_channel_block_idx)*input_height;\n" +" COMPUTE_FLOAT4 value=sample(nh,nw,inp_offset_base,input,input_height,input_width,paddingMode);\n" +" const int output_offset=((output_batch_idx*channelBlocks+output_channel_block_idx )*output_height+output_height_idx)*output_width+output_width_block_idx;\n" +" vstore4(CONVERT_FLOAT4(value),output_offset,output);\n" +"}\n" +"__kernel void bilinear_buf(GLOBAL_SIZE_3_DIMS __global const FLOAT* input,\n" +" __global const FLOAT* grid,\n" +" __global FLOAT* output,\n" +" __private const int input_height,\n" +" __private const int input_width,\n" +" __private const int output_height,\n" +" __private const int output_width,\n" +" __private const int channelBlocks,\n" +" __private const enum BorderMode paddingMode,\n" +" __private const int alignCorners){\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" const int output_batch_idx=output_batch_height_block_idx/output_height;\n" +" const int output_height_idx=output_batch_height_block_idx % output_height;\n" +" const int slice=output_height_idx/4;\n" +" const int slice_blocks=(output_height+3)/4;\n" +" // output_width_block_idx means gird y offset,2 means grid width\n" +" const int grid_offset=((output_batch_idx*slice_blocks+slice)*output_width+output_width_block_idx)*2;\n" +" COMPUTE_FLOAT4 grid_x=CONVERT_COMPUTE_FLOAT4(vload4(grid_offset,grid));\n" +" COMPUTE_FLOAT4 grid_y=CONVERT_COMPUTE_FLOAT4(vload4(grid_offset+1,grid));\n" +" const float arr[8]={grid_x.x,grid_y.x,grid_x.y,grid_y.y,grid_x.z,grid_y.z,grid_x.w,grid_y.w};\n" +" \n" +" // get grid x,y\n" +" const int arr_offset=output_height_idx % 4;\n" +" const float x=arr[2*arr_offset];\n" +" const float y=arr[2*arr_offset+1];\n" +" // convert grid x,y to input x,y coordinate range\n" +" float in_grid_x=getPosition(x,input_width,alignCorners);\n" +" float in_grid_y=getPosition(y,input_height,alignCorners);\n" +" int in_h0=floor(in_grid_y);\n" +" int in_w0=floor(in_grid_x);\n" +" int in_h1=ceil(in_grid_y);\n" +" int in_w1=ceil(in_grid_x);\n" +" float x_weight=in_w1-in_grid_x;\n" +" float y_weight=in_h1-in_grid_y;\n" +" // bilinear interpolation\n" +" const int inp_offset_base=(output_batch_idx*channelBlocks+output_channel_block_idx)*input_height;\n" +" COMPUTE_FLOAT4 i00=sample(in_h0,in_w0,inp_offset_base,input,input_height,input_width,paddingMode);\n" +" COMPUTE_FLOAT4 i01=sample(in_h0,in_w1,inp_offset_base,input,input_height,input_width,paddingMode);\n" +" COMPUTE_FLOAT4 i10=sample(in_h1,in_w0,inp_offset_base,input,input_height,input_width,paddingMode);\n" +" COMPUTE_FLOAT4 i11=sample(in_h1,in_w1,inp_offset_base,input,input_height,input_width,paddingMode);\n" +" COMPUTE_FLOAT4 value=CONVERT_COMPUTE_FLOAT4(((COMPUTE_FLOAT4)x_weight*CONVERT_COMPUTE_FLOAT4(i00)+(COMPUTE_FLOAT4)(1.0f-x_weight)*CONVERT_COMPUTE_FLOAT4(i01))*(COMPUTE_FLOAT4)y_weight +\n" +" ((COMPUTE_FLOAT4)x_weight*CONVERT_COMPUTE_FLOAT4(i10)+(COMPUTE_FLOAT4)(1.0f-x_weight)*CONVERT_COMPUTE_FLOAT4(i11))*(COMPUTE_FLOAT4)(1.0f- y_weight));\n" +" \n" +" const int output_offset=((output_batch_idx*channelBlocks+output_channel_block_idx )*output_height+output_height_idx)*output_width+output_width_block_idx;\n" +" vstore4(CONVERT_FLOAT4(value),output_offset,output);\n" +"}\n" +; +#endif +const char* interp = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void interp(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,__write_only image2d_t output,\n" +" __private const float height_scale,__private const float width_scale,\n" +" __private const float height_offset,__private const float width_offset,\n" +" __private const int input_height,__private const int input_width,\n" +" __private const int out_height) {\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" const int output_channel_block_idxs=global_size_dim0;\n" +" const int output_width=global_size_dim1;\n" +" const int output_batch_idx=output_batch_height_block_idx/out_height;\n" +" const int output_height_idx=output_batch_height_block_idx % out_height;\n" +" const float scale_height=output_height_idx*height_scale+height_offset;\n" +" const float scale_width=output_width_block_idx*width_scale+width_offset;\n" +"#define CLAMP(val,min_val,max_val) max(min(val,max_val),min_val)\n" +" const int height_floor=(int)floor(scale_height);\n" +" const int height_lf=CLAMP(height_floor,0,input_height-1);\n" +" const int height_uf=CLAMP(height_floor+1,0,input_height-1);\n" +" \n" +" const int width_floor=(int)floor(scale_width);\n" +" const int width_lf=CLAMP(width_floor,0,input_width-1);\n" +" const int width_uf=CLAMP(width_floor+1,0,input_width-1);\n" +" const float height_gap=scale_height-height_floor;\n" +" const float width_gap=scale_width-width_floor;\n" +" const int input_width_offset=mul24(output_channel_block_idx,input_width);\n" +" const int input_height_offset=mul24(output_batch_idx,input_height);\n" +" float4 top_left =\n" +" read_imagef(input,SAMPLER,(int2)(input_width_offset+width_lf,input_height_offset+height_lf));\n" +" float4 top_right =\n" +" read_imagef(input,SAMPLER,(int2)(input_width_offset+width_uf,input_height_offset+height_lf));\n" +" float4 bottom_left =\n" +" read_imagef(input,SAMPLER,(int2)(input_width_offset+width_lf,input_height_offset+height_uf));\n" +" float4 bottom_right =\n" +" read_imagef(input,SAMPLER,(int2)(input_width_offset+width_uf,input_height_offset+height_uf));\n" +" float4 top=mad((top_right-top_left),width_gap,top_left);\n" +" float4 bottom=mad((bottom_right-bottom_left),width_gap,bottom_left);\n" +" float4 out=mad((bottom-top),height_gap,top);\n" +" const int out_image_w=mad24(output_channel_block_idx,output_width,output_width_block_idx);\n" +" const int out_image_h=mad24(output_batch_idx,out_height,output_height_idx);\n" +" write_imagef(output,(int2)(out_image_w,out_image_h),out);\n" +"}\n" +; +const char* select = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void select_img(GLOBAL_SIZE_2_DIMS\n" +" __read_only image2d_t input,\n" +" __read_only image2d_t input0,\n" +" __read_only image2d_t input1,\n" +" __write_only image2d_t output\n" +" ) {\n" +" const int idx=get_global_id(0);\n" +" const int idy=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(idx,idy);\n" +" int4 select_vec=read_imagei(input,SAMPLER,(int2)(idx,idy));\n" +"#ifdef INSIZE1_EUQAL_1\n" +" FLOAT4 in0=RI_F(input0,SAMPLER,(int2)(0,0));\n" +" in0=(FLOAT4)(in0.x);\n" +"#else\n" +" FLOAT4 in0=RI_F(input0,SAMPLER,(int2)(idx,idy));\n" +"#endif\n" +" \n" +"#ifdef INSIZE2_EUQAL_1\n" +" FLOAT4 in1=RI_F(input1,SAMPLER,(int2)(0,0));\n" +" in1=(FLOAT4)(in1.x);\n" +"#else\n" +" FLOAT4 in1=RI_F(input1,SAMPLER,(int2)(idx,idy));\n" +"#endif\n" +" FLOAT4 out=select(in1,in0,select_vec == (int4)1);\n" +" WI_F(output,(int2)(idx,idy),out);\n" +"}\n" +; +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* range_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void range_buf(GLOBAL_SIZE_3_DIMS\n" +" __global const INPUT_TYPE* input0,\n" +" __global const INPUT_TYPE* input2,\n" +" __global OUTPUT_TYPE* output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel,\n" +" __private const int channelBlock\n" +" ) {\n" +" const int width_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int batch_idx=batch_channel_idx/channelBlock;\n" +" const int channel_idx=batch_channel_idx % channelBlock;\n" +" \n" +" const int offset=((((batch_idx*channelBlock)+channel_idx)*height+height_idx)*width+width_idx)*4;\n" +" const int channel4=channel_idx << 2;\n" +" int index=(((batch_idx*channel)+channel4)*height+height_idx)*width+width_idx;\n" +" int size=height*width;\n" +" int4 index4=(int4)(index,index+size,index+size*2,index+size*3);\n" +" INPUT_TYPE start=input0[0];\n" +" INPUT_TYPE step=input2[0];\n" +" OUTPUT_TYPE4 value=(OUTPUT_TYPE4)start+CONVERT_OUTPUT4(index4)*(OUTPUT_TYPE4)step;\n" +" vstore4(value,0,output+offset);\n" +"}\n" +; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* self_attention_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"#define DEAL_HEAD_DIM_NOT_ALIGN "" if(hd * 4 + 3 >= head_dim) {"" temp_0.w = (FLOAT)0;"" temp_1.w = (FLOAT)0;"" temp_2.w = (FLOAT)0;"" temp_3.w = (FLOAT)0;"" }"" if(hd * 4 + 2 >= head_dim) {"" temp_0.z = (FLOAT)0;"" temp_1.z = (FLOAT)0;"" temp_2.z = (FLOAT)0;"" temp_3.z = (FLOAT)0;"" }"" if(hd * 4 + 1 >= head_dim) {"" temp_0.y = (FLOAT)0;"" temp_1.y = (FLOAT)0;"" temp_2.y = (FLOAT)0;"" temp_3.y = (FLOAT)0;"" }\n" +"#define DEAL_SEQ_LEN_NOT_ALIGN "" if(4 * sl + 3 >= seq_len) {"" temp_3 = (FLOAT4)0;"" }"" if(4 * sl + 2 >= seq_len) {"" temp_2 = (FLOAT4)0;"" }"" if(4 * sl + 1 >= seq_len) {"" temp_1 = (FLOAT4)0;"" }\n" +"__kernel void split_transpose_qkv(GLOBAL_SIZE_3_DIMS\n" +" __global const FLOAT *input,// [Batch,seqLen/4,mNumHead*3*mHeadDim,4]\n" +" __global FLOAT *output_q,// [Batch*mNumHead,head_dim_pack_k,seq_len_pack_mn/qSeqSplitNum]\n" +" __global FLOAT *output_k,// [Batch*mNumHead,head_dim_pack_k,seq_len_pack_mn]\n" +" __global FLOAT *output_v,// [Batch*mNumHead,ROUND_UP(seqLen,tile),head_dim_pack_mn]\n" +" __private const int seq_len_pack_mn,\n" +" __private const int seq_len_piece,\n" +" __private const int head_dim_pack_mn,\n" +" __private const int head_dim_pack_k,\n" +" __private const int seq_len,\n" +" __private const int head_num,\n" +" __private const int head_dim,\n" +" __private const int seq_index\n" +") {\n" +" const int sl=get_global_id(0); // seqLen_4\n" +" const int hd=get_global_id(1); // mHeadDim_4\n" +" const int z=get_global_id(2); // Batch*mNumHead\n" +" DEAL_NON_UNIFORM_DIM3(sl,hd,z);\n" +" \n" +" const int b=z/head_num;\n" +" const int hn=z % head_num;\n" +" \n" +" const int seq_len_4=(seq_len+3)/4;\n" +" const int offset_q=((b*head_num+hn)*head_dim_pack_k+4*hd)*seq_len_piece+4*sl;\n" +" if(seq_index>0) {\n" +" // fill output_q only\n" +" if(sl*4 >= seq_len || hd*4 >= head_dim) {\n" +" if(hd*4= seq_len || hd*4 >= head_dim) {\n" +" if(hd*4 reduce: inside\n" +"__kernel void softmax_inside(GLOBAL_SIZE_3_DIMS\n" +" __global const FLOAT *input,// [batch*mNumHead,ROUND_UP(seqLen,tile),ROUND_UP(seqLen,tile)]\n" +" __global FLOAT *output,\n" +" __private const int inside_len,\n" +" __private const int4 shape // [batch*mNumHead,ROUND_UP(seqLen,tile),ROUND_UP(seqLen,tile)]\n" +" ) {\n" +" const int inside=get_global_id(0);\n" +" const int axis=get_global_id(1);\n" +" const int outside=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(inside,axis,outside);\n" +" const int offset=(outside*shape.y+axis)*shape.z+0;\n" +" int lid=get_local_id(0);\n" +" float local sum[SOFTMAX_LOCAL_SIZE];\n" +" /*Compute Max */\n" +" float maxValue=(float)(-FLT_MAX);\n" +" // clip to seq_len\n" +" for (int i=lid; i0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid [N Y X]\n" +"__kernel void trans_3d_buf(__global const FLOAT* input,\n" +" __global FLOAT* output,\n" +" __private const int batch,\n" +" __private const int width,\n" +" __private const int height\n" +") {\n" +" int b=get_global_id(2);\n" +" \n" +" const int lidw=get_local_id(0);\n" +" const int lidh=get_local_id(1);\n" +" // group id\n" +" const int w=get_group_id(0)*WGSW;\n" +" const int h=get_group_id(1)*WGSH;\n" +" int iw=lidw;\n" +" int jh=lidh;\n" +" \n" +" __local FLOAT4 localData[WGSW][WGSH/4];//w64h64\n" +" \n" +" #pragma unroll\n" +" for(int i=0; i= seq_len_4) {\n" +" return;\n" +" }\n" +" const int seq_len_pack=seq_len_piece;//((seq_len+tile-1)/tile)*tile;\n" +" const int head_dim_pack=((head_dim+tile-1)/tile)*tile;\n" +" \n" +" const int offset_inp=((b*head_num+hn)*head_dim_pack+4*hd)*seq_len_pack+4*sl;\n" +" \n" +" const int offset_out=(((b*seq_len_4+seq_index*seq_len_piece/4+sl)*head_num+hn)*head_dim+4*hd)*4;\n" +" \n" +" // Q\n" +" FLOAT4 temp_0=vload4(0,input+offset_inp);\n" +" FLOAT4 temp_1=vload4(0,input+offset_inp+seq_len_pack);\n" +" FLOAT4 temp_2=vload4(0,input+offset_inp+2*seq_len_pack);\n" +" FLOAT4 temp_3=vload4(0,input+offset_inp+3*seq_len_pack);\n" +" \n" +" vstore4(temp_0,0,output+offset_out);\n" +" if(4*hd+1>head_dim) return;\n" +" vstore4(temp_1,0,output+offset_out+4);\n" +" if(4*hd+2>head_dim) return;\n" +" vstore4(temp_2,0,output+offset_out+8);\n" +" if(4*hd+3>head_dim) return;\n" +" vstore4(temp_3,0,output+offset_out+12);\n" +"}\n" +; +#endif +const char* performance = +"#define MAD_V4(x, y) "" x = mad(y, x, y); "" y = mad(x, y, x); "" x = mad(y, x, y); "" y=mad(x,y,x);\n" +"#define MAD_V16(x, y) "" MAD_V4(x, y); "" MAD_V4(x, y); "" MAD_V4(x, y); "" MAD_V4(x,y);\n" +"#define MAD_V64(x, y) "" MAD_V16(x, y); "" MAD_V16(x, y); "" MAD_V16(x, y); "" MAD_V16(x,y);\n" +"#define MAD_V128(x, y) "" MAD_V64(x, y); "" MAD_V64(x, y); "" MAD_V64(x, y); "" MAD_V64(x,y);\n" +"#define MAD_V256(x, y) "" MAD_V128(x, y); "" MAD_V128(x, y); "" MAD_V128(x, y); "" MAD_V128(x,y);\n" +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__kernel void float_precision(__global float* output_ptr,float mul_value) {\n" +" float mul_x=mul_value;\n" +" float mul_y=(float)get_local_id(0);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" output_ptr[get_global_id(0)]=mul_y;\n" +"}\n" +"__kernel void half4_precision(__global half* output_ptr,float mul_value) {\n" +" half mul=(half)mul_value;\n" +" half4 mul_x=(half4)(mul);\n" +" half4 mul_y=(half4)get_local_id(0);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" MAD_V256(mul_x,mul_y);\n" +" output_ptr[get_global_id(0)]=(mul_y.S0)+(mul_y.S1)+(mul_y.S2)+(mul_y.S3);\n" +"}\n" +; +const char* winogradTransformSource2_3_1 = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void winogradTransformSource(__read_only image2d_t uInput,// 0\n" +" __write_only image2d_t uOutput,__private const int unitWidth,\n" +" __private const int unitHeight,// 3\n" +" __private const int padX,__private const int padY,\n" +" __private const int srcWidth,// 6\n" +" __private const int srcHeight,__private const int srcChannelC4,\n" +" __private const int batchOffset) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" if (pos.x= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S00=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S10=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S20=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S30=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S01=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S11=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S21=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S31=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S02=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S12=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S22=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S32=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S03=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S13=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S23=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S33=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" FLOAT4 m00=+S00-S02;\n" +" FLOAT4 m10=+S10-S12;\n" +" FLOAT4 m20=+S20-S22;\n" +" FLOAT4 m30=+S30-S32;\n" +" FLOAT4 m01=+(FLOAT)0.5f*S01+(FLOAT)0.5f*S02;\n" +" FLOAT4 m11=+(FLOAT)0.5f*S11+(FLOAT)0.5f*S12;\n" +" FLOAT4 m21=+(FLOAT)0.5f*S21+(FLOAT)0.5f*S22;\n" +" FLOAT4 m31=+(FLOAT)0.5f*S31+(FLOAT)0.5f*S32;\n" +" FLOAT4 m02=-(FLOAT)0.5f*S01+(FLOAT)0.5f*S02;\n" +" FLOAT4 m12=-(FLOAT)0.5f*S11+(FLOAT)0.5f*S12;\n" +" FLOAT4 m22=-(FLOAT)0.5f*S21+(FLOAT)0.5f*S22;\n" +" FLOAT4 m32=-(FLOAT)0.5f*S31+(FLOAT)0.5f*S32;\n" +" FLOAT4 m03=-S01+S03;\n" +" FLOAT4 m13=-S11+S13;\n" +" FLOAT4 m23=-S21+S23;\n" +" FLOAT4 m33=-S31+S33;\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*0),+m00-m20);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*1),+(FLOAT)0.5f*m10+(FLOAT)0.5f*m20);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*2),-(FLOAT)0.5f*m10+(FLOAT)0.5f*m20);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*3),-m10+m30);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*4),+m01-m21);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*5),+(FLOAT)0.5f*m11+(FLOAT)0.5f*m21);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*6),-(FLOAT)0.5f*m11+(FLOAT)0.5f*m21);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*7),-m11+m31);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*8),+m02-m22);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*9),+(FLOAT)0.5f*m12+(FLOAT)0.5f*m22);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*10),-(FLOAT)0.5f*m12+(FLOAT)0.5f*m22);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*11),-m12+m32);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*12),+m03-m23);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*13),+(FLOAT)0.5f*m13+(FLOAT)0.5f*m23);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*14),-(FLOAT)0.5f*m13+(FLOAT)0.5f*m23);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*15),-m13+m33);\n" +" }\n" +" }\n" +"}\n" +; +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* gemv_conv1x1_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_DIM2 "" __private int global_size_dim0,__private int global_size_dim1,\n" +"#define UNIFORM_BOUNDRY_CHECK(index0, index1) "" if(index0 >= global_size_dim0 || index1 >= global_size_dim1) { "" return; "" }\n" +"#define UCHAR16_TO_2CHAR16(a, b, c) "" a.s0 = (c.s0 >> 4) - 8; a.s1 = (c.s0 & 15) - 8; a.s2 = (c.s1 >> 4) - 8; a.s3 = (c.s1 & 15) - 8; a.s4 = (c.s2 >> 4) - 8; a.s5 = (c.s2 & 15) - 8; a.s6 = (c.s3 >> 4) - 8; a.s7 = (c.s3 & 15) - 8; "" a.s8 = (c.s4 >> 4) - 8; a.s9 = (c.s4 & 15) - 8; a.sa = (c.s5 >> 4) - 8; a.sb = (c.s5 & 15) - 8; a.sc = (c.s6 >> 4) - 8; a.sd = (c.s6 & 15) - 8; a.se = (c.s7 >> 4) - 8; a.sf = (c.s7 & 15) - 8; "" b.s0 = (c.s8 >> 4) - 8; b.s1 = (c.s8 & 15) - 8; b.s2 = (c.s9 >> 4) - 8; b.s3 = (c.s9 & 15) - 8; b.s4 = (c.sa >> 4) - 8; b.s5 = (c.sa & 15) - 8; b.s6 = (c.sb >> 4) - 8; b.s7 = (c.sb & 15) - 8; "" b.s8=(c.sc >> 4)-8; b.s9=(c.sc & 15)-8; b.sa=(c.sd >> 4)-8; b.sb=(c.sd & 15)-8; b.sc=(c.se >> 4)-8; b.sd=(c.se & 15)-8; b.se=(c.sf >> 4)-8; b.sf=(c.sf & 15)-8;\n" +"#define UCHAR8_TO_CHAR16(a, c) "" a.s0 = (c.s0 >> 4) - 8; a.s1 = (c.s0 & 15) - 8; a.s2 = (c.s1 >> 4) - 8; a.s3 = (c.s1 & 15) - 8; a.s4 = (c.s2 >> 4) - 8; a.s5 = (c.s2 & 15) - 8; a.s6 = (c.s3 >> 4) - 8; a.s7 = (c.s3 & 15) - 8; "" a.s8=(c.s4 >> 4)-8; a.s9=(c.s4 & 15)-8; a.sa=(c.s5 >> 4)-8; a.sb=(c.s5 & 15)-8; a.sc=(c.s6 >> 4)-8; a.sd=(c.s6 & 15)-8; a.se=(c.s7 >> 4)-8; a.sf=(c.s7 & 15)-8;\n" +"#define DOT16X16(a, b, c) "" c += dot(a.s0123, b.s0123); "" c += dot(a.s4567, b.s4567); "" c += dot(a.s89ab, b.s89ab); "" c += dot(a.scdef,b.scdef);\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" #define PADZEROS(k, channel, data) {"" COMPUTE_FLOAT* ptr = (COMPUTE_FLOAT*)&data; "" int remain = k + 15 - channel; "" for(int r = remain; r >= 0; r--){ "" ptr[15 - remain] = 0; "" } "" }\n" +"#else\n" +" #define PADZEROS(k,channel,data)\n" +"#endif\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void gemm_conv_c4_buf(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT* output,\n" +" __private const int dstChannelC4,\n" +" __private const int srcChannelC4,\n" +" __private const int srcChannel,\n" +" __private const int batch,\n" +" __private const int height,\n" +" __private const int width,\n" +" __private const int blockNum,\n" +" __private const int blockDim) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" UNIFORM_BOUNDRY_CHECK(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/width;\n" +" const int out_w_idx=out_c_w_idx % width;\n" +"#ifdef BACTH_BLOCK4\n" +" const int out_b_idx=(out_b_h_idx/height) << 2;\n" +"#else\n" +" const int out_b_idx=out_b_h_idx/height;\n" +"#endif\n" +" const int out_h_idx=out_b_h_idx % height;\n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out=bias0;\n" +"#ifdef BACTH_BLOCK4\n" +" COMPUTE_FLOAT4 out1=bias0,out2=bias0,out3=bias0;\n" +" int input_offset1=(((out_b_idx+1)*srcChannelC4*height+out_h_idx)*width+out_w_idx)*4;\n" +" int input_offset2=(((out_b_idx+2)*srcChannelC4*height+out_h_idx)*width+out_w_idx)*4;\n" +" int input_offset3=(((out_b_idx+3)*srcChannelC4*height+out_h_idx)*width+out_w_idx)*4;\n" +" bool isValidBatch1=out_b_idx+1= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void buffer_set_zero(\n" +" GLOBAL_SIZE_2_DIMS\n" +" __global OUTPUT_TYPE *output\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(x,y);\n" +" \n" +" output[y*global_size_dim0+x]=(OUTPUT_TYPE)(0);\n" +"}\n" +"__kernel void image_set_zero(\n" +" GLOBAL_SIZE_2_DIMS\n" +" __write_only image2d_t output\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(x,y);\n" +" WI_DATA(output,(int2)(x,y),(OUTPUT_TYPE_I4)(0));\n" +"}\n" +"__kernel void raster_buffer_direct(\n" +" GLOBAL_SIZE_3_DIMS\n" +" __read_only image2d_t input,\n" +" __private const int inputOffset,\n" +" __private const int combineSrcOffset,\n" +" __private const int inputStride0,\n" +" __private const int inputStride1,\n" +" __private const int inputStride2,\n" +" __private const int src_width,\n" +" __private const int src_height,\n" +" __private const int src_channel,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int outputOffset,\n" +" __private const int combineDstOffset,\n" +" __private const int outputStride0,\n" +" __private const int outputStride1,\n" +" __private const int outputStride2,\n" +" __private const int global_size0\n" +" ) {\n" +" const int idx=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" const int z=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(idx,y,z);\n" +" const int x=idx % global_size0;\n" +" const int id=idx/global_size0;\n" +" \n" +" int inputIndex=inputOffset+id*combineSrcOffset+z*inputStride0+y*inputStride1+x*inputStride2;\n" +" int outputIndex=outputOffset+id*combineDstOffset+z*outputStride0+y*outputStride1+x*outputStride2;\n" +"#ifdef INPUT_DATA_FORMAT_NHWC\n" +" int in_c=inputIndex % src_channel; inputIndex /= src_channel;\n" +" int in_w=inputIndex % src_width; inputIndex /= src_width;\n" +" int in_h=inputIndex % src_height;\n" +" int in_b=inputIndex/src_height;\n" +"#else\n" +" int in_w=inputIndex % src_width; inputIndex /= src_width;\n" +" int in_h=inputIndex % src_height; inputIndex /= src_height;\n" +" int in_c=inputIndex % src_channel;\n" +" int in_b=inputIndex/src_channel;\n" +"#endif\n" +" int2 coord=(int2)((in_c/4)*src_width+in_w,in_b*src_height+in_h);\n" +" INPUT_TYPE_I4 value=RI_DATA(input,SAMPLER,coord);\n" +" INPUT_TYPE_I* value_ptr=(INPUT_TYPE_I*)&value;\n" +" output[outputIndex]=(OUTPUT_TYPE)value_ptr[in_c % 4];\n" +"}\n" +"__kernel void raster_image(\n" +" GLOBAL_SIZE_3_DIMS\n" +" __read_only image2d_t input,\n" +" __private const int inputOffset,\n" +" __private const int inputStride0,\n" +" __private const int inputStride1,\n" +" __private const int inputStride2,\n" +" __private const int inputHeight,\n" +" __private const int inputWidth,\n" +" __private const int inputChannel,\n" +" __write_only image2d_t output,\n" +" __private const int outputOffset,\n" +" __private const int outputStride0,\n" +" __private const int outputStride1,\n" +" __private const int outputStride2,\n" +" __private const int outputHeight,\n" +" __private const int outputWidth,\n" +" __private const int outputChannel\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" const int z=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(x,y,z);\n" +" \n" +" int inputIndex=inputOffset+(z*inputStride0+y*inputStride1+x*inputStride2)*4;\n" +" int outputIndex=outputOffset+(z*outputStride0+y*outputStride1+x*outputStride2)*4;\n" +" int inp_idx_n=inputIndex/((inputChannel+3)/4*inputHeight*inputWidth*4);\n" +" int inputIndex_left=inputIndex % ((inputChannel+3)/4*inputHeight*inputWidth*4);\n" +" int inp_idx_c4=inputIndex_left/(inputHeight*inputWidth*4);\n" +" inputIndex_left=inputIndex_left % (inputHeight*inputWidth*4);\n" +" int inp_idx_h=inputIndex_left/(inputWidth*4);\n" +" inputIndex_left=inputIndex_left % (inputWidth*4);\n" +" int inp_idx_w=inputIndex_left/4;\n" +" \n" +" int out_idx_n=outputIndex/((outputChannel+3)/4*outputHeight*outputWidth*4);\n" +" int outputIndex_left=outputIndex % ((outputChannel+3)/4*outputHeight*outputWidth*4);\n" +" int out_idx_c4=outputIndex_left/(outputHeight*outputWidth*4);\n" +" outputIndex_left=outputIndex_left % (outputHeight*outputWidth*4);\n" +" int out_idx_h=outputIndex_left/(outputWidth*4);\n" +" outputIndex_left=outputIndex_left % (outputWidth*4);\n" +" int out_idx_w=outputIndex_left/4;\n" +" \n" +" int inp_idx0=inp_idx_c4*inputWidth+inp_idx_w;\n" +" int inp_idx1=inp_idx_n*inputHeight+inp_idx_h;\n" +" int out_idx0=out_idx_c4*outputWidth+out_idx_w;\n" +" int out_idx1=out_idx_n*outputHeight+out_idx_h;\n" +" INPUT_TYPE_I4 out=RI_DATA(input,SAMPLER,(int2)(inp_idx0,inp_idx1));\n" +" WI_DATA(output,(int2)(out_idx0,out_idx1),CONVERT_OUTPUT_I4(out));\n" +"}\n" +; #ifndef MNN_OPENCL_BUFFER_CLOSED #ifdef MNN_SUPPORT_INTEL_SUBGROUP -{ - "conv_2d_c1_subgroup_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x67,0x72,0x6f,0x75,0x70,0x73,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x5f,0x75,0x73,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x32,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x32,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x5f,0x75,0x73,0x32,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x34,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x5f,0x75,0x73,0x34,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x38,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x38,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x5f,0x75,0x73,0x38,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x75,0x73,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x32,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x75,0x73,0x32,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x32,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x34,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x75,0x73,0x34,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x34,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x38,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x75,0x73,0x38,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x38,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x28,0x64,0x61,0x74,0x61,0x29,0x2c,0x20,0x69,0x64,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x32,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x32,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x32,0x28,0x64,0x61,0x74,0x61,0x29,0x2c,0x20,0x69,0x64,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x34,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x34,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x34,0x28,0x64,0x61,0x74,0x61,0x29,0x2c,0x20,0x69,0x64,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x38,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x38,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x38,0x28,0x64,0x61,0x74,0x61,0x29,0x2c,0x20,0x69,0x64,0x29,0x29,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x32,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x32,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x32,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x34,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x38,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x38,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x38,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x32,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x32,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x34,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x34,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x34,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x38,0x28,0x70,0x74,0x72,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x76,0x61,0x6c,0x29,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x38,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x74,0x72,0x29,0x20,0x2b,0x20,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x38,0x28,0x76,0x61,0x6c,0x29,0x29,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x32,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x34,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x38,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x64,0x29,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x62,0x75,0x66,0x5f,0x73,0x75,0x62,0x67,0x72,0x6f,0x75,0x70,0x5f,0x63,0x31,0x5f,0x63,0x34,0x5f,0x62,0x32,0x28,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x29,0xa,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x25,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x2f,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x3d,0x20,0x78,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x32,0x35,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x3d,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x25,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x2f,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6b,0x77,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x77,0x65,0x69,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x63,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x32,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x32,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x20,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x25,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x72,0x63,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x2c,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x6c,0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x6c,0x69,0x64,0x20,0x2f,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x32,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x34,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x20,0x2a,0x20,0x34,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x32,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x62,0x75,0x66,0x5f,0x73,0x75,0x62,0x67,0x72,0x6f,0x75,0x70,0x5f,0x63,0x31,0x5f,0x63,0x34,0x5f,0x62,0x34,0x28,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x29,0xa,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x25,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x2f,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x3d,0x20,0x78,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x32,0x35,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x3d,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x25,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x2f,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6b,0x77,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x77,0x65,0x69,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x63,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x34,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x20,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x25,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x72,0x63,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x2c,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x6c,0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x6c,0x69,0x64,0x20,0x2f,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x34,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x20,0x2a,0x20,0x34,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x62,0x75,0x66,0x5f,0x73,0x75,0x62,0x67,0x72,0x6f,0x75,0x70,0x5f,0x63,0x31,0x5f,0x63,0x34,0x5f,0x62,0x38,0x28,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x29,0xa,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x25,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x2f,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x3d,0x20,0x78,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x34,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x32,0x35,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x3d,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x25,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x2f,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6b,0x77,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x77,0x65,0x69,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x63,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x38,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x20,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x25,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x72,0x63,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x2c,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x6c,0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x6c,0x69,0x64,0x20,0x2f,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x34,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x63,0x6b,0x20,0x2a,0x20,0x34,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x62,0x75,0x66,0x5f,0x73,0x75,0x62,0x67,0x72,0x6f,0x75,0x70,0x5f,0x63,0x31,0x5f,0x63,0x31,0x36,0x5f,0x62,0x32,0x28,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x29,0xa,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x25,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x2f,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x3d,0x20,0x78,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x32,0x35,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x3d,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x25,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x2f,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6b,0x77,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x77,0x65,0x69,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x63,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x32,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x32,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x20,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x25,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x72,0x63,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x2c,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x32,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x78,0x20,0x2b,0x20,0x32,0x20,0x3c,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x25,0x20,0x32,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x32,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x32,0x28,0x64,0x73,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x25,0x20,0x32,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x62,0x75,0x66,0x5f,0x73,0x75,0x62,0x67,0x72,0x6f,0x75,0x70,0x5f,0x63,0x31,0x5f,0x63,0x31,0x36,0x5f,0x62,0x34,0x28,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x29,0xa,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x25,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x2f,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x3d,0x20,0x78,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x32,0x35,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x3d,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x25,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x2f,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6b,0x77,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x77,0x65,0x69,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x63,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x34,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x20,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x25,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x72,0x63,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x2c,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x78,0x20,0x2b,0x20,0x34,0x20,0x3c,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x25,0x20,0x34,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x64,0x73,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x25,0x20,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x6e,0x76,0x5f,0x32,0x64,0x5f,0x62,0x75,0x66,0x5f,0x73,0x75,0x62,0x67,0x72,0x6f,0x75,0x70,0x5f,0x63,0x31,0x5f,0x63,0x31,0x36,0x5f,0x62,0x38,0x28,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x29,0xa,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x25,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x28,0x78,0x79,0x20,0x2f,0x20,0x78,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x3d,0x20,0x78,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x32,0x35,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x62,0x69,0x61,0x73,0x65,0x73,0x2c,0x20,0x62,0x69,0x61,0x73,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x3d,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x25,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x62,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x65,0x6c,0x65,0x6d,0x20,0x2f,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x20,0x2b,0x20,0x79,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x20,0x2b,0x20,0x78,0x62,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x66,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x62,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6b,0x77,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x77,0x65,0x69,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x63,0x20,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x73,0x76,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x38,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x20,0x20,0x3d,0x20,0x28,0x6b,0x77,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x57,0x49,0x44,0x54,0x48,0x20,0x2a,0x20,0x69,0x20,0x2b,0x20,0x28,0x6b,0x68,0x2a,0x44,0x49,0x4c,0x41,0x54,0x49,0x4f,0x4e,0x5f,0x48,0x45,0x49,0x47,0x48,0x54,0x29,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x25,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x63,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0x3b,0x20,0x69,0x63,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x73,0x72,0x63,0x20,0x3d,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x48,0x55,0x46,0x46,0x4c,0x45,0x28,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x63,0x20,0x2a,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2b,0x20,0x62,0x75,0x66,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x2c,0x20,0x62,0x75,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x77,0x65,0x69,0x5b,0x69,0x63,0x5d,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x64,0x73,0x74,0x5b,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x73,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x62,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x66,0x73,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x79,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x66,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x26,0x26,0x20,0x28,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x78,0x20,0x2b,0x20,0x38,0x20,0x3c,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x25,0x20,0x38,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x38,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x28,0x64,0x73,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x25,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x78,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x64,0x73,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d, } - }, +const char* conv_2d_c1_subgroup_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#pragma OPENCL EXTENSION cl_intel_subgroups : enable\n" +"#ifdef MNN_SUPPORT_FP16\n" +"#define GROUP_READ(ptr,offset) as_half(intel_sub_group_block_read_us((const __global ushort*)(ptr)+(offset)))\n" +"#define GROUP_READ2(ptr,offset) as_half2(intel_sub_group_block_read_us2((const __global ushort*)(ptr)+(offset)))\n" +"#define GROUP_READ4(ptr,offset) as_half4(intel_sub_group_block_read_us4((const __global ushort*)(ptr)+(offset)))\n" +"#define GROUP_READ8(ptr,offset) as_half8(intel_sub_group_block_read_us8((const __global ushort*)(ptr)+(offset)))\n" +"#define GROUP_WRITE(ptr,offset,val) intel_sub_group_block_write_us((const __global ushort*)(ptr)+(offset),as_ushort(val))\n" +"#define GROUP_WRITE2(ptr,offset,val) intel_sub_group_block_write_us2((const __global ushort*)(ptr)+(offset),as_ushort2(val))\n" +"#define GROUP_WRITE4(ptr,offset,val) intel_sub_group_block_write_us4((const __global ushort*)(ptr)+(offset),as_ushort4(val))\n" +"#define GROUP_WRITE8(ptr,offset,val) intel_sub_group_block_write_us8((const __global ushort*)(ptr)+(offset),as_ushort8(val))\n" +"#define GROUP_SHUFFLE(data,id) as_half(intel_sub_group_shuffle(as_ushort(data),id))\n" +"#define GROUP_SHUFFLE2(data,id) as_half2(intel_sub_group_shuffle(as_ushort2(data),id))\n" +"#define GROUP_SHUFFLE4(data,id) as_half4(intel_sub_group_shuffle(as_ushort4(data),id))\n" +"#define GROUP_SHUFFLE8(data,id) as_half8(intel_sub_group_shuffle(as_ushort8(data),id))\n" +"#else\n" +"#define GROUP_READ(ptr,offset) as_float(intel_sub_group_block_read((const __global uint*)(ptr)+(offset)))\n" +"#define GROUP_READ2(ptr,offset) as_float2(intel_sub_group_block_read2((const __global uint*)(ptr)+(offset)))\n" +"#define GROUP_READ4(ptr,offset) as_float4(intel_sub_group_block_read4((const __global uint*)(ptr)+(offset)))\n" +"#define GROUP_READ8(ptr,offset) as_float8(intel_sub_group_block_read8((const __global uint*)(ptr)+(offset)))\n" +"#define GROUP_WRITE(ptr,offset,val) intel_sub_group_block_write((const __global uint*)(ptr)+(offset),as_uint(val))\n" +"#define GROUP_WRITE2(ptr,offset,val) intel_sub_group_block_write2((const __global uint*)(ptr)+(offset),as_uint2(val))\n" +"#define GROUP_WRITE4(ptr,offset,val) intel_sub_group_block_write4((const __global uint*)(ptr)+(offset),as_uint4(val))\n" +"#define GROUP_WRITE8(ptr,offset,val) intel_sub_group_block_write8((const __global uint*)(ptr)+(offset),as_uint8(val))\n" +"#define GROUP_SHUFFLE(data,id) intel_sub_group_shuffle(data,id)\n" +"#define GROUP_SHUFFLE2(data,id) intel_sub_group_shuffle(data,id)\n" +"#define GROUP_SHUFFLE4(data,id) intel_sub_group_shuffle(data,id)\n" +"#define GROUP_SHUFFLE8(data,id) intel_sub_group_shuffle(data,id)\n" +"#endif\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void conv_2d_buf_subgroup_c1_c4_b2(\n" +" __global FLOAT* input,\n" +" __global FLOAT* output,\n" +" __global FLOAT* weights,\n" +" __global FLOAT* biases,\n" +" __private const int pad_width,\n" +" __private const int pad_height,\n" +" __private const int input_width,\n" +" __private const int input_height,\n" +" __private const int output_width,\n" +" __private const int output_height,\n" +" __private const int output_channel,\n" +" __private const int x_blocks,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right\n" +")\n" +"{\n" +" const int f_block=get_group_id(1);\n" +" const int lid=get_sub_group_local_id();\n" +" const int b=get_global_id(2);\n" +" const int xy=get_global_id(0);\n" +" const int x=(xy % x_blocks) << 1;\n" +" const int y=(xy/x_blocks);\n" +" const int input_x=x*STRIDE_WIDTH-pad_width;\n" +" const int input_y=y*STRIDE_HEIGHT-pad_height;\n" +" const uint input_x_pitch=1;\n" +" const uint input_y_pitch=input_x_pitch*input_width;\n" +" const uint input_f_pitch=input_y_pitch*input_height;\n" +" const uint input_b_pitch=input_f_pitch*INPUT_CHANNEL;\n" +" const uint input_offset=b*input_b_pitch +\n" +" input_y*input_y_pitch +\n" +" input_x*input_x_pitch;\n" +" const uint output_pack=(output_channel+3)/4;\n" +" const uint output_x_pitch=4;\n" +" const uint output_y_pitch=output_x_pitch*output_width;\n" +" const uint output_fs_pitch=output_y_pitch*output_height;\n" +" const uint output_b_pitch=output_fs_pitch*output_pack;\n" +" \n" +" \n" +" const uint output_offset=b*output_b_pitch +\n" +" f_block*4*output_fs_pitch +\n" +" y*output_y_pitch +\n" +" x*output_x_pitch;\n" +" const uint filter_isv_pitch=16;\n" +" const uint filter_x_pitch=256;\n" +" const uint filter_y_pitch=filter_x_pitch*FILTER_WIDTH;\n" +" const uint filter_is_pitch=filter_y_pitch*FILTER_HEIGHT;\n" +" const uint filter_os_pitch=filter_is_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint filter_offset=f_block*filter_os_pitch;\n" +" uint bias_offset=f_block*16;\n" +" COMPUTE_FLOAT2 dst=(COMPUTE_FLOAT2)(GROUP_READ(biases,bias_offset));\n" +" \n" +" FLOAT line_cache[INPUT_CHANNEL*INPUT_BLOCK_SIZE];\n" +" for (int ic=0; ic= 0 && input_y+yb= 0 && input_x+xb= output_channel) {\n" +" for (int i=0; i<2 && (x+i)= 0 && input_y+yb= 0 && input_x+xb= output_channel) {\n" +" for (int i=0; i<4 && (x+i)= 0 && input_y+yb= 0 && input_x+xb= output_channel) {\n" +" for (int i=0; i<8 && (x+i)= 0 && input_y+yb= 0 && input_x+xb= output_channel) {\n" +" for (int i=0; i<2; i++) {\n" +" if ((f_block*16+lid= 0 && input_y+yb= 0 && input_x+xb= output_channel) {\n" +" for (int i=0; i<4; i++) {\n" +" if ((f_block*16+lid= 0 && input_y+yb= 0 && input_x+xb= output_channel) {\n" +" for (int i=0; i<8; i++) {\n" +" if ((f_block*16+lid= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"#define MOD_NUM 15\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" #define PADZEROSVEC(k, channel, data0, data1, data2, data3) "" data0 = (k << 2) < channel ? data0 : 0; "" data1 = (k << 2) + 1 < channel ? data1 : 0; "" data2 = (k << 2) + 2 < channel ? data2 : 0; "" data3=(k << 2)+3> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale+offset;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale+offset;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale+offset;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale+offset;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" \n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" }\n" +" weight_offset += 4*filter_hw.y;\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" \n" +"}\n" +"__kernel\n" +"void conv_2d_int_c4h1w2(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#else\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,//generate width's num\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks,\n" +" __private const int blockDim) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=(out_c_w_idx % out_w_blocks) << 1;\n" +" const int out_b_idx=out_b_h_idx/out_hw.x;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" \n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out0=bias0;\n" +" COMPUTE_FLOAT4 out1=bias0;\n" +" \n" +" const int in_w0_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_w1_idx_base=in_w0_idx_base+stride_hw.y;\n" +" const int in_h_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" \n" +" const int kh_start=select(0,(-in_h_idx_base+dilate_hw.x-1)/dilate_hw.x,in_h_idx_base<0);\n" +" const int in_h_idx_start=mad24(kh_start,dilate_hw.x,in_h_idx_base);\n" +" const int in_h_idx_end=min(mad24(filter_hw.x,dilate_hw.x,in_h_idx_base),in_hw.x);\n" +" \n" +" const int weight_oc_offset=out_c_blocks*filter_hw.x*filter_hw.y*4;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw.y) ? (FLOAT4)0 : vload4(in_w0_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=CONVERT_COMPUTE_FLOAT4((in_w1_idx<0 || in_w1_idx >= in_hw.y) ? (FLOAT4)0 : vload4(in_w1_idx,input+inp_offset_base));\n" +" \n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,weight+weight_offset);\n" +" char4 charWeight1=vload4(0,weight+weight_offset+weight_oc_offset);\n" +" char4 charWeight2=vload4(0,weight+weight_offset+weight_oc_offset*2);\n" +" char4 charWeight3=vload4(0,weight+weight_offset+weight_oc_offset*3);\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale+offset;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale+offset;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale+offset;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale+offset;\n" +"#else\n" +" uchar2 charWeightInt40=vload2(0,weight+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,weight+weight_offset/2+weight_oc_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,weight+weight_offset/2+weight_oc_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,weight+weight_offset/2+weight_oc_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale+offset;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale+offset;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale+offset;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale+offset;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" \n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" if(out_w_idx+1 >= out_hw.y) return;\n" +" vstore4(CONVERT_FLOAT4(out1),1,output+out_offset);\n" +"#else\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_int_c4h1w4(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#else\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks,\n" +" __private const int blockDim) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=(out_c_w_idx % out_w_blocks) << 2;\n" +" const int out_b_idx=out_b_h_idx/out_hw.x;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out0=bias0;\n" +" COMPUTE_FLOAT4 out1=bias0;\n" +" COMPUTE_FLOAT4 out2=bias0;\n" +" COMPUTE_FLOAT4 out3=bias0;\n" +" const int in_w0_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_w1_idx_base=in_w0_idx_base+stride_hw.y;\n" +" const int in_w2_idx_base=in_w1_idx_base+stride_hw.y;\n" +" const int in_w3_idx_base=in_w2_idx_base+stride_hw.y;\n" +" const int in_h_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" \n" +" const int kh_start=select(0,(-in_h_idx_base+dilate_hw.x-1)/dilate_hw.x,in_h_idx_base<0);\n" +" const int in_h_idx_start=mad24(kh_start,dilate_hw.x,in_h_idx_base);\n" +" const int in_h_idx_end=min(mad24(filter_hw.x,dilate_hw.x,in_h_idx_base),in_hw.x);\n" +" \n" +" const int weight_oc_offset=out_c_blocks*filter_hw.x*filter_hw.y*4;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw.y) ? (FLOAT4)0 : vload4(in_w0_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=CONVERT_COMPUTE_FLOAT4((in_w1_idx<0 || in_w1_idx >= in_hw.y) ? (FLOAT4)0 : vload4(in_w1_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=CONVERT_COMPUTE_FLOAT4((in_w2_idx<0 || in_w2_idx >= in_hw.y) ? (FLOAT4)0 : vload4(in_w2_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=CONVERT_COMPUTE_FLOAT4((in_w3_idx<0 || in_w3_idx >= in_hw.y) ? (FLOAT4)0 : vload4(in_w3_idx,input+inp_offset_base));\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,weight+weight_offset);\n" +" char4 charWeight1=vload4(0,weight+weight_offset+weight_oc_offset);\n" +" char4 charWeight2=vload4(0,weight+weight_offset+weight_oc_offset*2);\n" +" char4 charWeight3=vload4(0,weight+weight_offset+weight_oc_offset*3);\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale+offset;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale+offset;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale+offset;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale+offset;\n" +"#else\n" +" uchar2 charWeightInt40=vload2(0,weight+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,weight+weight_offset/2+weight_oc_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,weight+weight_offset/2+weight_oc_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,weight+weight_offset/2+weight_oc_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale+offset;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale+offset;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale+offset;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale+offset;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +" \n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.y-out_w_idx;\n" +" if (remain >= 4) {\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_int_c4h4w1(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#else\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks,\n" +" __private const int blockDim) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h_blocks;//equal to in_b_idx\n" +" const int out_h_idx=(out_b_h_idx % out_h_blocks) << 2;\n" +" \n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out0=bias0;\n" +" COMPUTE_FLOAT4 out1=bias0;\n" +" COMPUTE_FLOAT4 out2=bias0;\n" +" COMPUTE_FLOAT4 out3=bias0;\n" +" const int in_w_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_h0_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" const int in_h1_idx_base=in_h0_idx_base+stride_hw.x;\n" +" const int in_h2_idx_base=in_h1_idx_base+stride_hw.x;\n" +" const int in_h3_idx_base=in_h2_idx_base+stride_hw.x;\n" +" \n" +" const int kw_start=select(0,(-in_w_idx_base+dilate_hw.y-1)/dilate_hw.y,in_w_idx_base<0);\n" +" const int in_w_idx_start=mad24(kw_start,dilate_hw.y,in_w_idx_base);\n" +" const int in_w_idx_end=min(mad24(filter_hw.y,dilate_hw.y,in_w_idx_base),in_hw.y);\n" +" \n" +" const int weight_oc_offset=out_c_blocks*filter_hw.x*filter_hw.y*4;\n" +" const int in_hw_size=in_hw.x*in_hw.y;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw_size) ? (FLOAT4)0 : vload4(in_h0_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=CONVERT_COMPUTE_FLOAT4((in_h1_idx<0 || in_h1_idx >= in_hw_size) ? (FLOAT4)0 : vload4(in_h1_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=CONVERT_COMPUTE_FLOAT4((in_h2_idx<0 || in_h2_idx >= in_hw_size) ? (FLOAT4)0 : vload4(in_h2_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=CONVERT_COMPUTE_FLOAT4((in_h3_idx<0 || in_h3_idx >= in_hw_size) ? (FLOAT4)0 : vload4(in_h3_idx+fw,input+inp_offset_base));\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,weight+weight_offset);\n" +" char4 charWeight1=vload4(0,weight+weight_offset+weight_oc_offset);\n" +" char4 charWeight2=vload4(0,weight+weight_offset+weight_oc_offset*2);\n" +" char4 charWeight3=vload4(0,weight+weight_offset+weight_oc_offset*3);\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale+offset;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale+offset;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale+offset;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale+offset;\n" +"#else\n" +" uchar2 charWeightInt40=vload2(0,weight+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,weight+weight_offset/2+weight_oc_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,weight+weight_offset/2+weight_oc_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,weight+weight_offset/2+weight_oc_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale+offset;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale+offset;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale+offset;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale+offset;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +" \n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.x-out_h_idx;\n" +" if(remain >= 4){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_int_c8h4w1(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#else\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks,\n" +" __private const int blockDim) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h_blocks;//equal to in_b_idx\n" +" const int out_h_idx=(out_b_h_idx % out_h_blocks) << 2;\n" +" \n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out0=bias0;\n" +" COMPUTE_FLOAT4 out1=bias0;\n" +" COMPUTE_FLOAT4 out2=bias0;\n" +" COMPUTE_FLOAT4 out3=bias0;\n" +" COMPUTE_FLOAT4 bias1=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx+1,bias));\n" +" COMPUTE_FLOAT4 out4=bias1;\n" +" COMPUTE_FLOAT4 out5=bias1;\n" +" COMPUTE_FLOAT4 out6=bias1;\n" +" COMPUTE_FLOAT4 out7=bias1;\n" +" const int in_w_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_h0_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" const int in_h1_idx_base=in_h0_idx_base+stride_hw.x;\n" +" const int in_h2_idx_base=in_h1_idx_base+stride_hw.x;\n" +" const int in_h3_idx_base=in_h2_idx_base+stride_hw.x;\n" +" \n" +" const int kw_start=select(0,(-in_w_idx_base+dilate_hw.y-1)/dilate_hw.y,in_w_idx_base<0);\n" +" const int in_w_idx_start=mad24(kw_start,dilate_hw.y,in_w_idx_base);\n" +" const int in_w_idx_end=min(mad24(filter_hw.y,dilate_hw.y,in_w_idx_base),in_hw.y);\n" +" \n" +" const int weight_oc_offset=filter_hw.x*filter_hw.y*4;\n" +" const int weight_ic_offset=out_c_blocks*weight_oc_offset;\n" +" const int in_hw_size=in_hw.x*in_hw.y;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw_size) ? (FLOAT4)0 : vload4(in_h0_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=CONVERT_COMPUTE_FLOAT4((in_h1_idx<0 || in_h1_idx >= in_hw_size) ? (FLOAT4)0 : vload4(in_h1_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=CONVERT_COMPUTE_FLOAT4((in_h2_idx<0 || in_h2_idx >= in_hw_size) ? (FLOAT4)0 : vload4(in_h2_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=CONVERT_COMPUTE_FLOAT4((in_h3_idx<0 || in_h3_idx >= in_hw_size) ? (FLOAT4)0 : vload4(in_h3_idx+fw,input+inp_offset_base));\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,weight+weight_offset);\n" +" char4 charWeight1=vload4(0,weight+weight_offset+weight_ic_offset);\n" +" char4 charWeight2=vload4(0,weight+weight_offset+weight_ic_offset*2);\n" +" char4 charWeight3=vload4(0,weight+weight_offset+weight_ic_offset*3);\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale0+offset0;\n" +"#else\n" +" uchar2 charWeightInt40=vload2(0,weight+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,weight+weight_offset/2+weight_ic_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,weight+weight_offset/2+weight_ic_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,weight+weight_offset/2+weight_ic_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)- 8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale0+offset0;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" charWeight0=vload4(0,weight+weight_offset+weight_oc_offset);\n" +" charWeight1=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset);\n" +" charWeight2=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*2);\n" +" charWeight3=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*3);\n" +" weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale1+offset1;\n" +" weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale1+offset1;\n" +" weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale1+offset1;\n" +" weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale1+offset1;\n" +"#else\n" +" charWeightInt40=vload2(0,weight+weight_offset/2+weight_oc_offset/2);\n" +" charWeightInt41=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2);\n" +" charWeightInt42=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset*2/2);\n" +" charWeightInt43=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset*3/2);\n" +" charWeight0=(char4)(0,0,0,0);\n" +" charWeight1=(char4)(0,0,0,0);\n" +" charWeight2=(char4)(0,0,0,0);\n" +" charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)- 8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)- 8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale1+offset1;\n" +" weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale1+offset1;\n" +" weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale1+offset1;\n" +" weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale1+offset1;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" out4=mad(in0.x,weight0,out4);\n" +" out4=mad(in0.y,weight1,out4);\n" +" out4=mad(in0.z,weight2,out4);\n" +" out4=mad(in0.w,weight3,out4);\n" +" \n" +" out5=mad(in1.x,weight0,out5);\n" +" out5=mad(in1.y,weight1,out5);\n" +" out5=mad(in1.z,weight2,out5);\n" +" out5=mad(in1.w,weight3,out5);\n" +" \n" +" out6=mad(in2.x,weight0,out6);\n" +" out6=mad(in2.y,weight1,out6);\n" +" out6=mad(in2.z,weight2,out6);\n" +" out6=mad(in2.w,weight3,out6);\n" +" \n" +" out7=mad(in3.x,weight0,out7);\n" +" out7=mad(in3.y,weight1,out7);\n" +" out7=mad(in3.z,weight2,out7);\n" +" out7=mad(in3.w,weight3,out7);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +" out4=fmax(out4,(COMPUTE_FLOAT4)0);\n" +" out5=fmax(out5,(COMPUTE_FLOAT4)0);\n" +" out6=fmax(out6,(COMPUTE_FLOAT4)0);\n" +" out7=fmax(out7,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out4=clamp(out4,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out5=clamp(out5,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out6=clamp(out6,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out7=clamp(out7,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.x-out_h_idx;\n" +" if(remain >= 4){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" if(remain >= 4){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out7),3*out_hw.y,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2*out_hw.y,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out7),3*out_hw.y,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_int_c8h2w1(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#else\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks,\n" +" __private const int blockDim) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h_blocks;//equal to in_b_idx\n" +" const int out_h_idx=(out_b_h_idx % out_h_blocks) << 1;\n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out0=bias0;\n" +" COMPUTE_FLOAT4 out1=bias0;\n" +" COMPUTE_FLOAT4 bias1=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx+1,bias));\n" +" COMPUTE_FLOAT4 out2=bias1;\n" +" COMPUTE_FLOAT4 out3=bias1;\n" +" const int in_w_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_h0_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" const int in_h1_idx_base=in_h0_idx_base+stride_hw.x;\n" +" \n" +" const int kw_start=select(0,(-in_w_idx_base+dilate_hw.y-1)/dilate_hw.y,in_w_idx_base<0);\n" +" const int in_w_idx_start=mad24(kw_start,dilate_hw.y,in_w_idx_base);\n" +" const int in_w_idx_end=min(mad24(filter_hw.y,dilate_hw.y,in_w_idx_base),in_hw.y);\n" +" \n" +" const int weight_oc_offset=filter_hw.x*filter_hw.y*4;\n" +" const int weight_ic_offset=out_c_blocks*weight_oc_offset;\n" +" const int in_hw_size=in_hw.x*in_hw.y;\n" +" // weight: [ic/4,oc,4],loop: ic/4\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw_size) ? (FLOAT4)0 : vload4(in_h0_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=CONVERT_COMPUTE_FLOAT4((in_h1_idx<0 || in_h1_idx >= in_hw_size) ? (FLOAT4)0 : vload4(in_h1_idx+fw,input+inp_offset_base));\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,weight+weight_offset);\n" +" char4 charWeight1=vload4(0,weight+weight_offset+weight_ic_offset);\n" +" char4 charWeight2=vload4(0,weight+weight_offset+weight_ic_offset*2);\n" +" char4 charWeight3=vload4(0,weight+weight_offset+weight_ic_offset*3);\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale0+offset0;\n" +"#else\n" +" uchar2 charWeightInt40=vload2(0,weight+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,weight+weight_offset/2+weight_ic_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,weight+weight_offset/2+weight_ic_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,weight+weight_offset/2+weight_ic_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale0+offset0;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" charWeight0=vload4(0,weight+weight_offset+weight_oc_offset);\n" +" charWeight1=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset);\n" +" charWeight2=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*2);\n" +" charWeight3=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*3);\n" +" weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale1+offset1;\n" +" weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale1+offset1;\n" +" weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale1+offset1;\n" +" weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale1+offset1;\n" +"#else\n" +" charWeightInt40=vload2(0,weight+weight_offset/2+weight_oc_offset/2);\n" +" charWeightInt41=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2);\n" +" charWeightInt42=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset*2/2);\n" +" charWeightInt43=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset*3/2);\n" +" charWeight0=(char4)(0,0,0,0);\n" +" charWeight1=(char4)(0,0,0,0);\n" +" charWeight2=(char4)(0,0,0,0);\n" +" charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0& MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1& MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0& MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1& MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0& MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1& MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0& MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1& MOD_NUM)-8;\n" +" weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale1+offset1;\n" +" weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale1+offset1;\n" +" weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale1+offset1;\n" +" weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale1+offset1;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" out2=mad(in0.x,weight0,out2);\n" +" out2=mad(in0.y,weight1,out2);\n" +" out2=mad(in0.z,weight2,out2);\n" +" out2=mad(in0.w,weight3,out2);\n" +" \n" +" out3=mad(in1.x,weight0,out3);\n" +" out3=mad(in1.y,weight1,out3);\n" +" out3=mad(in1.z,weight2,out3);\n" +" out3=mad(in1.w,weight3,out3);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.x-out_h_idx;\n" +" if(remain >= 2){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" if(remain >= 2){\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),out_hw.y,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_int_c8h1w4(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#else\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks,\n" +" __private const int blockDim) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=(out_c_w_idx % out_w_blocks) << 2;\n" +" const int out_b_idx=out_b_h_idx/out_hw.x;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" \n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out0=bias0;\n" +" COMPUTE_FLOAT4 out1=bias0;\n" +" COMPUTE_FLOAT4 out2=bias0;\n" +" COMPUTE_FLOAT4 out3=bias0;\n" +" COMPUTE_FLOAT4 bias1=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx+1,bias));\n" +" COMPUTE_FLOAT4 out4=bias1;\n" +" COMPUTE_FLOAT4 out5=bias1;\n" +" COMPUTE_FLOAT4 out6=bias1;\n" +" COMPUTE_FLOAT4 out7=bias1;\n" +" const int in_w0_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_w1_idx_base=in_w0_idx_base+stride_hw.y;\n" +" const int in_w2_idx_base=in_w1_idx_base+stride_hw.y;\n" +" const int in_w3_idx_base=in_w2_idx_base+stride_hw.y;\n" +" const int in_h_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" \n" +" const int kh_start=select(0,(-in_h_idx_base+dilate_hw.x-1)/dilate_hw.x,in_h_idx_base<0);\n" +" const int in_h_idx_start=mad24(kh_start,dilate_hw.x,in_h_idx_base);\n" +" const int in_h_idx_end=min(mad24(filter_hw.x,dilate_hw.x,in_h_idx_base),in_hw.x);\n" +" \n" +" const int weight_oc_offset=filter_hw.x*filter_hw.y*4;\n" +" const int weight_ic_offset=out_c_blocks*weight_oc_offset;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw.y) ? (FLOAT4)0 : vload4(in_w0_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=CONVERT_COMPUTE_FLOAT4((in_w1_idx<0 || in_w1_idx >= in_hw.y) ? (FLOAT4)0 : vload4(in_w1_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=CONVERT_COMPUTE_FLOAT4((in_w2_idx<0 || in_w2_idx >= in_hw.y) ? (FLOAT4)0 : vload4(in_w2_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=CONVERT_COMPUTE_FLOAT4((in_w3_idx<0 || in_w3_idx >= in_hw.y) ? (FLOAT4)0 : vload4(in_w3_idx,input+inp_offset_base));\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" char4 charWeight0=vload4(0,weight+weight_offset);\n" +" char4 charWeight1=vload4(0,weight+weight_offset+weight_ic_offset);\n" +" char4 charWeight2=vload4(0,weight+weight_offset+weight_ic_offset*2);\n" +" char4 charWeight3=vload4(0,weight+weight_offset+weight_ic_offset*3);\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale0+offset0;\n" +"#else\n" +" uchar2 charWeightInt40=vload2(0,weight+weight_offset/2);\n" +" uchar2 charWeightInt41=vload2(0,weight+weight_offset/2+weight_ic_offset/2);\n" +" uchar2 charWeightInt42=vload2(0,weight+weight_offset/2+weight_ic_offset*2/2);\n" +" uchar2 charWeightInt43=vload2(0,weight+weight_offset/2+weight_ic_offset*3/2);\n" +" char4 charWeight0=(char4)(0,0,0,0);\n" +" char4 charWeight1=(char4)(0,0,0,0);\n" +" char4 charWeight2=(char4)(0,0,0,0);\n" +" char4 charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)-8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale0+offset0;\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale0+offset0;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +" \n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" charWeight0=vload4(0,weight+weight_offset+weight_oc_offset);\n" +" charWeight1=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset);\n" +" charWeight2=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*2);\n" +" charWeight3=vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*3);\n" +" weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale1+offset1;\n" +" weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale1+offset1;\n" +" weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale1+offset1;\n" +" weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale1+offset1;\n" +"#else\n" +" charWeightInt40=vload2(0,weight+weight_offset/2+weight_oc_offset/2);\n" +" charWeightInt41=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset/2);\n" +" charWeightInt42=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset*2/2);\n" +" charWeightInt43=vload2(0,weight+weight_offset/2+weight_oc_offset/2+weight_ic_offset*3/2);\n" +" charWeight0=(char4)(0,0,0,0);\n" +" charWeight1=(char4)(0,0,0,0);\n" +" charWeight2=(char4)(0,0,0,0);\n" +" charWeight3=(char4)(0,0,0,0);\n" +" charWeight0.x=(charWeightInt40.s0 >> 4)-8;\n" +" charWeight0.y=(charWeightInt40.s0 & MOD_NUM)-8;\n" +" charWeight0.z=(charWeightInt40.s1 >> 4)-8;\n" +" charWeight0.w=(charWeightInt40.s1 & MOD_NUM)-8;\n" +" charWeight1.x=(charWeightInt41.s0 >> 4)-8;\n" +" charWeight1.y=(charWeightInt41.s0 & MOD_NUM)- 8;\n" +" charWeight1.z=(charWeightInt41.s1 >> 4)-8;\n" +" charWeight1.w=(charWeightInt41.s1 & MOD_NUM)-8;\n" +" charWeight2.x=(charWeightInt42.s0 >> 4)-8;\n" +" charWeight2.y=(charWeightInt42.s0 & MOD_NUM)-8;\n" +" charWeight2.z=(charWeightInt42.s1 >> 4)-8;\n" +" charWeight2.w=(charWeightInt42.s1 & MOD_NUM)-8;\n" +" charWeight3.x=(charWeightInt43.s0 >> 4)-8;\n" +" charWeight3.y=(charWeightInt43.s0 & MOD_NUM)-8;\n" +" charWeight3.z=(charWeightInt43.s1 >> 4)-8;\n" +" charWeight3.w=(charWeightInt43.s1 & MOD_NUM)-8;\n" +" weight0=CONVERT_COMPUTE_FLOAT4(charWeight0)*scale1+offset1;\n" +" weight1=CONVERT_COMPUTE_FLOAT4(charWeight1)*scale1+offset1;\n" +" weight2=CONVERT_COMPUTE_FLOAT4(charWeight2)*scale1+offset1;\n" +" weight3=CONVERT_COMPUTE_FLOAT4(charWeight3)*scale1+offset1;\n" +"#endif\n" +" PADZEROSVEC(in_c_idx,inChannel,weight0,weight1,weight2,weight3);\n" +" \n" +" out4=mad(in0.x,weight0,out4);\n" +" out4=mad(in0.y,weight1,out4);\n" +" out4=mad(in0.z,weight2,out4);\n" +" out4=mad(in0.w,weight3,out4);\n" +" \n" +" out5=mad(in1.x,weight0,out5);\n" +" out5=mad(in1.y,weight1,out5);\n" +" out5=mad(in1.z,weight2,out5);\n" +" out5=mad(in1.w,weight3,out5);\n" +" \n" +" out6=mad(in2.x,weight0,out6);\n" +" out6=mad(in2.y,weight1,out6);\n" +" out6=mad(in2.z,weight2,out6);\n" +" out6=mad(in2.w,weight3,out6);\n" +" \n" +" out7=mad(in3.x,weight0,out7);\n" +" out7=mad(in3.y,weight1,out7);\n" +" out7=mad(in3.z,weight2,out7);\n" +" out7=mad(in3.w,weight3,out7);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +" out4=fmax(out4,(COMPUTE_FLOAT4)0);\n" +" out5=fmax(out5,(COMPUTE_FLOAT4)0);\n" +" out6=fmax(out6,(COMPUTE_FLOAT4)0);\n" +" out7=fmax(out7,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out4=clamp(out4,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out5=clamp(out5,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out6=clamp(out6,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out7=clamp(out7,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.y-out_w_idx;\n" +" if(remain >= 4){\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks)return;\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" if(remain >= 4){\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out4,out5,out6,out7)),0,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5)),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5)),0,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks)return;\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out4,out5,out6,out7)),0,output+out_offset);\n" +"#endif\n" +"}\n" +; #endif #ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "interp_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6e,0x65,0x61,0x72,0x65,0x73,0x74,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x55,0x53,0x45,0x5f,0x52,0x4f,0x55,0x4e,0x44,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2e,0x34,0x39,0x39,0x66,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x30,0x2e,0x34,0x39,0x39,0x66,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2d,0x31,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2d,0x31,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6c,0x69,0x6e,0x65,0x61,0x72,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x30,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x30,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x31,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2b,0x31,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x31,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x2b,0x31,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x77,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x68,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x30,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x30,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x30,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x30,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x30,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x31,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x31,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x31,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x30,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x31,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x31,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x31,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x30,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x30,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x30,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x30,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x31,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x31,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x31,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x31,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x28,0x31,0x2e,0x30,0x2d,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x77,0x29,0x2a,0x28,0x31,0x2e,0x30,0x2d,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x68,0x29,0x29,0x2a,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x30,0x30,0x29,0x20,0x2b,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x77,0x2a,0x28,0x31,0x2e,0x30,0x2d,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x68,0x29,0x29,0x2a,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x30,0x31,0x29,0x20,0x2b,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x28,0x31,0x2e,0x30,0x2d,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x77,0x29,0x2a,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x68,0x29,0x2a,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x31,0x30,0x29,0x20,0x2b,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x77,0x2a,0x66,0x61,0x63,0x74,0x6f,0x72,0x5f,0x68,0x29,0x2a,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x31,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6e,0x65,0x61,0x72,0x65,0x73,0x74,0x33,0x44,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x64,0x65,0x70,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x64,0x65,0x70,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x64,0x65,0x70,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x64,0x65,0x70,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x64,0x65,0x70,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x64,0x65,0x70,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x64,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x64,0x65,0x70,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x64,0x65,0x70,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x73,0x63,0x61,0x6c,0x65,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x64,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x64,0x5f,0x69,0x64,0x78,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2d,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x30,0x2c,0x20,0x28,0x69,0x6e,0x74,0x29,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2d,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x64,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x64,0x65,0x70,0x74,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x7d, } - }, +const char* interp_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void nearest_buf(GLOBAL_SIZE_3_DIMS __global const FLOAT* input,\n" +" __global FLOAT* output,\n" +" __private const float height_scale,\n" +" __private const float width_scale,\n" +" __private const float height_offset,\n" +" __private const float width_offset,\n" +" __private const int input_height,\n" +" __private const int input_width,\n" +" __private const int out_height,\n" +" __private const int out_width,\n" +" __private const int channelBlocks) {\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" const int output_batch_idx=output_batch_height_block_idx/out_height;\n" +" const int output_height_idx=output_batch_height_block_idx % out_height;\n" +" const float in_h_idx=output_height_idx*height_scale+height_offset;\n" +" const float in_w_idx=output_width_block_idx*width_scale+width_offset;\n" +"#ifdef USE_ROUND\n" +" const int in_h_index=min(max(0,(int)floor(in_h_idx+0.499f)),input_height-1);\n" +" const int in_w_index=min(max(0,(int)floor(in_w_idx+0.499f)),input_width-1);\n" +"#else\n" +" const int in_h_index=min(max(0,(int)floor(in_h_idx)),input_height-1);\n" +" const int in_w_index=min(max(0,(int)floor(in_w_idx)),input_width-1);\n" +"#endif\n" +" const int inp_offset=((output_batch_idx*channelBlocks+output_channel_block_idx)*input_height+in_h_index)*input_width+in_w_index;\n" +" FLOAT4 value=vload4(inp_offset,input);\n" +" const int out_offset=((output_batch_idx*channelBlocks+output_channel_block_idx)*out_height+output_height_idx)*out_width+output_width_block_idx;\n" +" vstore4(value,out_offset,output);\n" +"}\n" +"__kernel void bilinear_buf(GLOBAL_SIZE_3_DIMS __global const FLOAT* input,\n" +" __global FLOAT* output,\n" +" __private const float height_scale,\n" +" __private const float width_scale,\n" +" __private const float height_offset,\n" +" __private const float width_offset,\n" +" __private const int input_height,\n" +" __private const int input_width,\n" +" __private const int out_height,\n" +" __private const int out_width,\n" +" __private const int channelBlocks) {\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" \n" +" const int output_batch_idx=output_batch_height_block_idx/out_height;\n" +" const int output_height_idx=output_batch_height_block_idx % out_height;\n" +" const float in_h_idx=output_height_idx*height_scale+height_offset;\n" +" const float in_w_idx=output_width_block_idx*width_scale+width_offset;\n" +" const int in_h0_index=min(max(0,(int)floor(in_h_idx)),input_height-1);\n" +" const int in_w0_index=min(max(0,(int)floor(in_w_idx)),input_width-1);\n" +" const int in_h1_index=min(max(0,(int)floor(in_h_idx)+1),input_height-1);\n" +" const int in_w1_index=min(max(0,(int)floor(in_w_idx)+1),input_width-1);\n" +" \n" +" float factor_w=(in_w_idx-(int)floor(in_w_idx));\n" +" float factor_h=(in_h_idx-(int)floor(in_h_idx));\n" +" \n" +" const int inp_offset_base=(output_batch_idx*channelBlocks+output_channel_block_idx)*input_height;\n" +" const int inp_offset_00=(inp_offset_base+in_h0_index)*input_width+in_w0_index;\n" +" const int inp_offset_01=(inp_offset_base+in_h0_index)*input_width+in_w1_index;\n" +" const int inp_offset_10=(inp_offset_base+in_h1_index)*input_width+in_w0_index;\n" +" const int inp_offset_11=(inp_offset_base+in_h1_index)*input_width+in_w1_index;\n" +" FLOAT4 value_00=vload4(inp_offset_00,input);\n" +" FLOAT4 value_01=vload4(inp_offset_01,input);\n" +" FLOAT4 value_10=vload4(inp_offset_10,input);\n" +" FLOAT4 value_11=vload4(inp_offset_11,input);\n" +" FLOAT4 value=CONVERT_FLOAT4((float4)((1.0-factor_w)*(1.0-factor_h))*convert_float4(value_00)+(float4)(factor_w*(1.0-factor_h))*convert_float4(value_01)+(float4)((1.0-factor_w)*factor_h)*convert_float4(value_10)+(float4)(factor_w*factor_h)*convert_float4(value_11));\n" +" \n" +" const int out_offset=((output_batch_idx*channelBlocks+output_channel_block_idx)*out_height+output_height_idx)*out_width+output_width_block_idx;\n" +" \n" +" vstore4(value,out_offset,output);\n" +"}\n" +"__kernel void nearest3D_buf(GLOBAL_SIZE_3_DIMS __global const FLOAT* input,\n" +" __global FLOAT* output,\n" +" __private const float depth_scale,\n" +" __private const float height_scale,\n" +" __private const float width_scale,\n" +" __private const float depth_offset,\n" +" __private const float height_offset,\n" +" __private const float width_offset,\n" +" __private const int input_depth,\n" +" __private const int input_height,\n" +" __private const int input_width,\n" +" __private const int out_depth,\n" +" __private const int out_height,\n" +" __private const int out_width,\n" +" __private const int channelBlocks) {\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_height_width_block_idx=get_global_id(1);\n" +" const int output_batch_depth_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_height_width_block_idx,output_batch_depth_block_idx);\n" +" const int output_batch_idx=output_batch_depth_block_idx/out_depth;\n" +" const int output_depth_idx=output_batch_depth_block_idx % out_depth;\n" +" const int output_height_idx=output_height_width_block_idx/out_height;\n" +" const int output_width_idx=output_height_width_block_idx % out_height;\n" +" const float in_d_idx=output_depth_idx*depth_scale+depth_offset;\n" +" const float in_h_idx=output_height_idx*height_scale+height_offset;\n" +" const float in_w_idx=output_width_idx*width_scale+width_offset;\n" +" const int in_d_index=min(max(0,(int)floor(in_d_idx)),input_depth-1);\n" +" const int in_h_index=min(max(0,(int)floor(in_h_idx)),input_height-1);\n" +" const int in_w_index=min(max(0,(int)floor(in_w_idx)),input_width-1);\n" +" const int inp_offset=(((output_batch_idx*channelBlocks+output_channel_block_idx)\n" +"*input_depth+in_d_index)*input_height+in_h_index)*input_width+in_w_index;\n" +" const int out_offset=(((output_batch_idx*channelBlocks+output_channel_block_idx)\n" +"*out_depth+output_depth_idx)*out_height+output_height_idx)*out_width+output_width_idx;\n" +" FLOAT4 value=vload4(inp_offset,input);\n" +" vstore4(value,out_offset,output);\n" +"}\n" +; #endif -{ - "scale", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x63,0x61,0x6c,0x65,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x48,0x41,0x53,0x5f,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x62,0x69,0x61,0x73,0x2c,0x20,0x2f,0x2a,0x20,0x63,0x6f,0x75,0x74,0x25,0x34,0x20,0x2a,0x20,0x63,0x6f,0x75,0x74,0x2f,0x34,0x20,0x2a,0x2f,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x62,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x77,0x2c,0x20,0x68,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2c,0x20,0x68,0x62,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x63,0x61,0x6c,0x65,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x73,0x63,0x61,0x6c,0x65,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x48,0x41,0x53,0x5f,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x69,0x61,0x73,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x62,0x69,0x61,0x73,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x69,0x6e,0x20,0x2a,0x20,0x73,0x63,0x61,0x6c,0x65,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x2b,0x20,0x62,0x69,0x61,0x73,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x69,0x6e,0x20,0x2a,0x20,0x73,0x63,0x61,0x6c,0x65,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2c,0x20,0x68,0x62,0x29,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x7d,0xa,0xa,0xa, } - }, -{ - "softmax", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x45,0x58,0x50,0x20,0x65,0x78,0x70,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x77,0x2c,0x20,0x62,0x68,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2c,0x20,0x62,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2c,0x20,0x62,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x77,0x63,0x2c,0x20,0x62,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x77,0x69,0x64,0x74,0x68,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x63,0x2c,0x20,0x62,0x68,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa, } - }, +const char* scale = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void scale(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,__read_only image2d_t scale,\n" +"#ifdef HAS_BIAS\n" +" __read_only image2d_t bias,/* cout%4*cout/4 */\n" +"#endif\n" +" __write_only image2d_t output) {\n" +" const int channel_block_idx=get_global_id(0);\n" +" const int w=get_global_id(1);\n" +" const int hb=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(channel_block_idx,w,hb);\n" +" const int width=global_size_dim1;\n" +" const int pos=mad24(channel_block_idx,width,w);\n" +" FLOAT4 in=RI_F(input,SAMPLER,(int2)(pos,hb));\n" +" FLOAT4 scale_value=RI_F(scale,SAMPLER,(int2)(channel_block_idx,0));\n" +"#ifdef HAS_BIAS\n" +" FLOAT4 bias_value=RI_F(bias,SAMPLER,(int2)(channel_block_idx,0));\n" +" FLOAT4 out=in*scale_value+bias_value;\n" +"#else\n" +" FLOAT4 out=in*scale_value;\n" +"#endif\n" +" WI_F(output,(int2)(pos,hb),out);\n" +"}\n" +; +const char* softmax = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define EXP exp\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void softmax_channel(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,__write_only image2d_t output,\n" +" __private const int remain_channels,__private const int4 shape // NCHW\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int w=get_global_id(1);\n" +" const int bh=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(x,w,bh);\n" +"#if SOFTMAX_LOCAL_SIZE >= 4\n" +" int lid=get_local_id(0);\n" +" FLOAT4 local sum[SOFTMAX_LOCAL_SIZE];\n" +" FLOAT4 maxValue=(FLOAT4)-FLT_MAX;\n" +" for (int i=lid; i0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid= 4\n" +" int lid=get_local_id(0);\n" +" FLOAT4 local sum[SOFTMAX_LOCAL_SIZE];\n" +" /*Compute Max */\n" +" FLOAT4 maxValue=(FLOAT4)(-FLT_MAX);\n" +" for (int i=lid; i0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid= 4\n" +" int lid=get_local_id(0);\n" +" FLOAT4 local sum[SOFTMAX_LOCAL_SIZE];\n" +" \n" +" /*Compute Max */\n" +" FLOAT4 maxValue=(FLOAT4)(-FLT_MAX);\n" +" for (int i=lid; i0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid= global_size_dim0 || index1 >= global_size_dim1) { "" return; "" }\n" +"#define GLOBAL_SIZE_DIM3 "" __private int global_size_dim0,__private int global_size_dim1,__private int global_size_dim2,\n" +"#define UNIFORM_BOUNDRY_CHECK3(index0, index1, index2) "" if(index0 >= global_size_dim0 || index1 >= global_size_dim1 || index2 >= global_size_dim2) { "" return; "" }\n" +"#define UCHAR16_TO_2CHAR16(a, b, c) "" a.s0 = (c.s0 >> 4) - 8; a.s1 = (c.s0 & 15) - 8; a.s2 = (c.s1 >> 4) - 8; a.s3 = (c.s1 & 15) - 8; a.s4 = (c.s2 >> 4) - 8; a.s5 = (c.s2 & 15) - 8; a.s6 = (c.s3 >> 4) - 8; a.s7 = (c.s3 & 15) - 8; "" a.s8 = (c.s4 >> 4) - 8; a.s9 = (c.s4 & 15) - 8; a.sa = (c.s5 >> 4) - 8; a.sb = (c.s5 & 15) - 8; a.sc = (c.s6 >> 4) - 8; a.sd = (c.s6 & 15) - 8; a.se = (c.s7 >> 4) - 8; a.sf = (c.s7 & 15) - 8; "" b.s0 = (c.s8 >> 4) - 8; b.s1 = (c.s8 & 15) - 8; b.s2 = (c.s9 >> 4) - 8; b.s3 = (c.s9 & 15) - 8; b.s4 = (c.sa >> 4) - 8; b.s5 = (c.sa & 15) - 8; b.s6 = (c.sb >> 4) - 8; b.s7 = (c.sb & 15) - 8; "" b.s8=(c.sc >> 4)-8; b.s9=(c.sc & 15)-8; b.sa=(c.sd >> 4)-8; b.sb=(c.sd & 15)-8; b.sc=(c.se >> 4)-8; b.sd=(c.se & 15)-8; b.se=(c.sf >> 4)-8; b.sf=(c.sf & 15)-8;\n" +"#define UCHAR8_TO_CHAR16(a, c) "" a.s0 = (c.s0 >> 4) - 8; a.s1 = (c.s0 & 15) - 8; a.s2 = (c.s1 >> 4) - 8; a.s3 = (c.s1 & 15) - 8; a.s4 = (c.s2 >> 4) - 8; a.s5 = (c.s2 & 15) - 8; a.s6 = (c.s3 >> 4) - 8; a.s7 = (c.s3 & 15) - 8; "" a.s8=(c.s4 >> 4)-8; a.s9=(c.s4 & 15)-8; a.sa=(c.s5 >> 4)-8; a.sb=(c.s5 & 15)-8; a.sc=(c.s6 >> 4)-8; a.sd=(c.s6 & 15)-8; a.se=(c.s7 >> 4)-8; a.sf=(c.s7 & 15)-8;\n" +"#define DOT16X16(a, b, c) "" c += dot(a.s0123, b.s0123); "" c += dot(a.s4567, b.s4567); "" c += dot(a.s89ab, b.s89ab); "" c += dot(a.scdef,b.scdef);\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void reshape_nchw4_nhwc4(GLOBAL_SIZE_DIM3\n" +"__global const FLOAT* input,\n" +"__global FLOAT* output,\n" +"__private const int width_height,\n" +"__private const int batch,\n" +"__private const int channel,\n" +"__private const int channelC4){\n" +" const int x=get_global_id(0); //c\n" +" const int y=get_global_id(1); //b\n" +" const int wh=get_global_id(2); // w*h\n" +" UNIFORM_BOUNDRY_CHECK3(x,y,wh);\n" +" \n" +" const int x4=x << 2;\n" +" const int y4=y << 2;\n" +" const int channel4=channelC4*4;\n" +" const int stride=channel4*width_height;\n" +" const int input_offset=(y4*channel4+x4)*width_height+wh*4;\n" +" const int output_offset=((y*width_height+wh)*channel4+x4)*4;\n" +" FLOAT4 in0=vload4(0,input+input_offset);\n" +" FLOAT4 in1=(y4+1= channel){\n" +" FLOAT *in0_ptr=(FLOAT*)&in0;\n" +" FLOAT *in1_ptr=(FLOAT*)&in1;\n" +" FLOAT *in2_ptr=(FLOAT*)&in2;\n" +" FLOAT *in3_ptr=(FLOAT*)&in3;\n" +" int remain=x4+3-channel;\n" +" for(int i=remain; i >= 0; i--){\n" +" in0_ptr[3-remain]=0;\n" +" in1_ptr[3-remain]=0;\n" +" in2_ptr[3-remain]=0;\n" +" in3_ptr[3-remain]=0;\n" +" }\n" +" }\n" +"#endif\n" +" \n" +" FLOAT16 out=(FLOAT16)(in0.s0,in1.s0,in2.s0,in3.s0,in0.s1,in1.s1,in2.s1,in3.s1,in0.s2,in1.s2,in2.s2,in3.s2,in0.s3,in1.s3,in2.s3,in3.s3);\n" +" \n" +" vstore16(out,0,output+output_offset);\n" +"}\n" +"__kernel void reshape_nhwc4_nchw4(GLOBAL_SIZE_DIM3\n" +"__global const FLOAT* input,\n" +"__global FLOAT* output,\n" +"__private const int width_height,\n" +"__private const int batch,\n" +"__private const int channelC4){\n" +" const int x=get_global_id(0); //c\n" +" const int y=get_global_id(1); //b\n" +" const int wh=get_global_id(2); //w*h\n" +" UNIFORM_BOUNDRY_CHECK3(x,y,wh);\n" +" \n" +" const int x4=x << 2;\n" +" const int y4=y << 2;\n" +" const int channel4=channelC4*4;\n" +" const int stride=channel4*width_height;\n" +" const int input_offset=((y*width_height+wh)*channel4+x4)*4;\n" +" const int output_offset=(y4*channel4+x4)*width_height+wh*4;\n" +" FLOAT16 in=vload16(0,input+input_offset);\n" +" \n" +" FLOAT4 out0=(FLOAT4)(in.s0,in.s4,in.s8,in.sc);\n" +" FLOAT4 out1=(FLOAT4)(in.s1,in.s5,in.s9,in.sd);\n" +" FLOAT4 out2=(FLOAT4)(in.s2,in.s6,in.sa,in.se);\n" +" FLOAT4 out3=(FLOAT4)(in.s3,in.s7,in.sb,in.sf);\n" +" \n" +" vstore4(out0,0,output+output_offset);\n" +" if(y4+1 >= batch) return;\n" +" vstore4(out1,0,output+output_offset+stride);\n" +" if(y4+2 >= batch) return;\n" +" vstore4(out2,0,output+output_offset+2*stride);\n" +" if(y4+3 >= batch) return;\n" +" vstore4(out3,0,output+output_offset+3*stride);\n" +"}\n" +"__kernel void gemm_b4_c4_buf(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *weight,\n" +"#endif\n" +" __global const float *dequantScaleOffset,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT* output,\n" +" __private const int dstChannelC4,\n" +" __private const int srcChannelC4,\n" +" __private const int blockNum,\n" +" __private const int blockDim) {\n" +" const int x=get_global_id(0); //c\n" +" const int y=get_global_id(1); //b\n" +" UNIFORM_BOUNDRY_CHECK(x,y);\n" +" const int out_c_idx=x;\n" +" const int out_b_idx=y << 2;\n" +" COMPUTE_FLOAT4 bias0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out=(COMPUTE_FLOAT4)bias0.s0;\n" +" COMPUTE_FLOAT4 out1=(COMPUTE_FLOAT4)bias0.s1,out2=(COMPUTE_FLOAT4)bias0.s2,out3=(COMPUTE_FLOAT4)bias0.s3;\n" +" \n" +" int input_offset=out_b_idx*srcChannelC4*4;\n" +" int out_offset=(out_b_idx*dstChannelC4+out_c_idx*4)*4;\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" int weight_offset=out_c_idx*4*8;\n" +" int weight_oc_offset=dstChannelC4*32;\n" +"#else\n" +" int weight_offset=out_c_idx*4*16;\n" +" int weight_oc_offset=dstChannelC4*64;\n" +"#endif\n" +" const int loop=(blockDim+15)/16;\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" const int loop_end=max(loop-1,0);\n" +" const int remain=blockDim-loop_end*16;\n" +"#else\n" +" const int loop_end=loop;\n" +"#endif\n" +" \n" +" for (int i=0; i= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void buffer_set_zero(\n" +" GLOBAL_SIZE_2_DIMS\n" +" __global OUTPUT_TYPE *output\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(x,y);\n" +" \n" +" output[y*global_size_dim0+x]=(OUTPUT_TYPE)(0.0f);\n" +"}\n" +"__kernel void raster_buffer(\n" +" GLOBAL_SIZE_3_DIMS\n" +" __global INPUT_TYPE *input,\n" +" __private const int inputOffset,\n" +" __private const int inputStride0,\n" +" __private const int inputStride1,\n" +" __private const int inputStride2,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int outputOffset,\n" +" __private const int outputStride0,\n" +" __private const int outputStride1,\n" +" __private const int outputStride2\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" const int z=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(x,y,z);\n" +" \n" +" int inputIndex=inputOffset+z*inputStride0+y*inputStride1+x*inputStride2;\n" +" int outputIndex=outputOffset+z*outputStride0+y*outputStride1+x*outputStride2;\n" +" output[outputIndex]=(OUTPUT_TYPE)input[inputIndex];\n" +"}\n" +"__kernel void raster_nc4hw4_buffer(\n" +" GLOBAL_SIZE_3_DIMS\n" +" __global INPUT_TYPE *input,\n" +" __private const int inputOffset,\n" +" __private const int inputStride0,\n" +" __private const int inputStride1,\n" +" __private const int inputStride2,\n" +" __private const int inputHeight,\n" +" __private const int inputWidth,\n" +" __private const int inputChannel,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int outputOffset,\n" +" __private const int outputStride0,\n" +" __private const int outputStride1,\n" +" __private const int outputStride2,\n" +" __private const int outputHeight,\n" +" __private const int outputWidth,\n" +" __private const int outputChannel\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" const int z=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(x,y,z);\n" +" \n" +" int inputIndex=inputOffset+(z*inputStride0+y*inputStride1+x*inputStride2)*4;\n" +" int outputIndex=outputOffset+(z*outputStride0+y*outputStride1+x*outputStride2)*4;\n" +" \n" +" vstore4(CONVERT_OUTPUT4(vload4(0,input+inputIndex)),0,output+outputIndex);\n" +"}\n" +"__kernel void raster_direct_buffer(\n" +" GLOBAL_SIZE_3_DIMS\n" +" __private const int size_x,\n" +" __global INPUT_TYPE *input,\n" +" __private const int inputOffset,\n" +" __private const int combineSrcOffset,\n" +" __private const int inputStride0,\n" +" __private const int inputStride1,\n" +" __private const int inputStride2,\n" +" __private const int src_width,\n" +" __private const int src_height,\n" +" __private const int src_channel,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int outputOffset,\n" +" __private const int combineDstOffset,\n" +" __private const int outputStride0,\n" +" __private const int outputStride1,\n" +" __private const int outputStride2,\n" +" __private const int dst_width,\n" +" __private const int dst_height,\n" +" __private const int dst_channel\n" +" ) {\n" +" const int idx=get_global_id(0);\n" +" const int y=get_global_id(1);\n" +" const int z=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(idx,y,z);\n" +" const int x=idx % size_x;\n" +" const int id=idx/size_x;\n" +" \n" +" int inputIndex=inputOffset+id*combineSrcOffset+z*inputStride0+y*inputStride1+x*inputStride2;\n" +" int outputIndex=outputOffset+id*combineDstOffset+z*outputStride0+y*outputStride1+x*outputStride2;\n" +"#ifdef INPUT_DATA_FORMAT_NHWC\n" +" int in_c=inputIndex % src_channel; inputIndex /= src_channel;\n" +" int in_w=inputIndex % src_width; inputIndex /= src_width;\n" +" int in_h=inputIndex % src_height;\n" +" int in_b=inputIndex/src_height;\n" +" int src_channel4=(src_channel+3)/4;\n" +" int inputIndexC4=(((in_b*src_channel4+(in_c/4))*src_height+in_h)*src_width+in_w)*4+(in_c % 4);\n" +"#else\n" +" int in_w=inputIndex % src_width; inputIndex /= src_width;\n" +" int in_h=inputIndex % src_height; inputIndex /= src_height;\n" +" int in_c=inputIndex % src_channel;\n" +" int in_b=inputIndex/src_channel;\n" +" int src_channel4=(src_channel+3)/4;\n" +" int inputIndexC4=(((in_b*src_channel4+(in_c/4))*src_height+in_h)*src_width+in_w)*4+(in_c % 4);\n" +"#endif\n" +" \n" +"#ifdef OUTPUT_DATA_FORMAT_NHWC\n" +" int out_c=outputIndex % dst_channel; outputIndex /= dst_channel;\n" +" int out_w=outputIndex % dst_width; outputIndex /= dst_width;\n" +" int out_h=outputIndex % dst_height;\n" +" int out_b=outputIndex/dst_height;\n" +" int dst_channel4=(dst_channel+3)/4;\n" +" int outputIndexC4=(((out_b*dst_channel4+(out_c/4))*dst_height+out_h)*dst_width+out_w)*4+(out_c % 4);\n" +"#else\n" +" int out_w=outputIndex % dst_width; outputIndex /= dst_width;\n" +" int out_h=outputIndex % dst_height; outputIndex /= dst_height;\n" +" int out_c=outputIndex % dst_channel;\n" +" int out_b=outputIndex/dst_channel;\n" +" int dst_channel4=(dst_channel+3)/4;\n" +" int outputIndexC4=(((out_b*dst_channel4+(out_c/4))*dst_height+out_h)*dst_width+out_w)*4+(out_c % 4);\n" +"#endif\n" +" \n" +" output[outputIndexC4]=(OUTPUT_TYPE)input[inputIndexC4];\n" +"}\n" +; #endif #ifndef MNN_OPENCL_BUFFER_CLOSED #ifdef MNN_SUPPORT_INTEL_SUBGROUP -{ - "binary_subgroup_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x49,0x20,0x33,0x2e,0x31,0x34,0x31,0x35,0x39,0x32,0x36,0x35,0x33,0x35,0x38,0x39,0x66,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x34,0x5f,0x63,0x34,0x5f,0x63,0x34,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x34,0x5f,0x63,0x34,0x5f,0x63,0x31,0x36,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x34,0x5f,0x63,0x31,0x36,0x5f,0x63,0x34,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x31,0x36,0x5f,0x63,0x34,0x5f,0x63,0x34,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x34,0x5f,0x63,0x31,0x36,0x5f,0x63,0x31,0x36,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x31,0x36,0x5f,0x63,0x34,0x5f,0x63,0x31,0x36,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x6c,0x75,0x5f,0x62,0x75,0x66,0x5f,0x63,0x34,0x5f,0x63,0x34,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x6c,0x75,0x5f,0x62,0x75,0x66,0x5f,0x63,0x34,0x5f,0x63,0x31,0x36,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x5f,0x6f,0x75,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x6c,0x75,0x5f,0x62,0x75,0x66,0x5f,0x63,0x31,0x36,0x5f,0x63,0x31,0x36,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x34,0x20,0x3e,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x25,0x20,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x6f,0x75,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x41,0x53,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x6c,0x75,0x5f,0x62,0x75,0x66,0x5f,0x63,0x31,0x36,0x5f,0x63,0x34,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x3c,0x3c,0x32,0x29,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x73,0x69,0x7a,0x65,0x20,0x3d,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x34,0x20,0x3e,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x3f,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x25,0x20,0x34,0x29,0x20,0x3a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x6f,0x75,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x31,0x36,0x5f,0x63,0x31,0x36,0x5f,0x63,0x31,0x36,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x30,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x31,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x30,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x31,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x29,0x29,0x29,0x20,0x3a,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x5b,0x30,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x29,0x29,0x20,0x3a,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x5b,0x30,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x34,0x20,0x3e,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x25,0x20,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x6f,0x75,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x57,0x52,0x49,0x54,0x45,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x41,0x53,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x5f,0x63,0x31,0x36,0x5f,0x63,0x31,0x36,0x5f,0x63,0x34,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x2f,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x29,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x61,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x30,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x31,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x30,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x30,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x31,0x36,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x72,0x63,0x31,0x5f,0x77,0x69,0x64,0x74,0x68,0x2b,0x77,0x5f,0x69,0x64,0x78,0x2b,0x69,0x6e,0x70,0x75,0x74,0x31,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x34,0x2b,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x29,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x77,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x30,0x29,0x29,0x29,0x29,0x20,0x3a,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x5b,0x30,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x41,0x53,0x5f,0x49,0x4e,0x50,0x55,0x54,0x5f,0x44,0x41,0x54,0x41,0x34,0x28,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x53,0x55,0x42,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x52,0x45,0x41,0x44,0x34,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x54,0x45,0x4c,0x5f,0x44,0x41,0x54,0x41,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x31,0x29,0x29,0x29,0x29,0x20,0x3a,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x5b,0x30,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x73,0x69,0x7a,0x65,0x20,0x3d,0x20,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x34,0x20,0x3e,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x3f,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x20,0x25,0x20,0x34,0x29,0x20,0x3a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x6f,0x75,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, +const char* binary_subgroup_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define PI 3.141592653589f\n" +"__kernel void binary_buf_c4_c4_c4(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __global INPUT_TYPE* input0,__global INPUT_TYPE* input1,__global OUTPUT_TYPE* output,\n" +" __private const int4 shape,//[N,H,W,C]\n" +" __private const int2 isFull,\n" +" __private const int activationType,\n" +" __private const int input0_pad_left,__private const int input0_pad_right,\n" +" __private const int input1_pad_left,__private const int input1_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" if (get_global_id(0) >= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" const int offset=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" \n" +" float4 in0=convert_float4(vload4(0,input0+offset*isFull.x));\n" +" float4 in1=convert_float4(vload4(0,input1+offset*isFull.y));\n" +" if(isFull.x == 0) {\n" +" in0=(float4)(in0.x,in0.x,in0.x,in0.x);\n" +" }\n" +" if(isFull.y == 0) {\n" +" in1=(float4)(in1.x,in1.x,in1.x,in1.x);\n" +" }\n" +" \n" +" float4 out=OPERATOR;\n" +" \n" +" if(activationType == 1) {\n" +" out=fmax(out,(float4)0);\n" +" }\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+offset);\n" +"}\n" +"__kernel void binary_buf_c4_c4_c16(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __global INPUT_TYPE* input0,__global INPUT_TYPE* input1,__global OUTPUT_TYPE* output,\n" +" __private const int4 shape,//[N,H,W,C]\n" +" __private const int2 isFull,\n" +" __private const int activationType,\n" +" __private const int input0_pad_left,__private const int input0_pad_right,\n" +" __private const int input1_pad_left,__private const int input1_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" if (get_global_id(0) >= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int channel16=(shape.w+15)/16;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" const int dst_width=shape.z+output_pad_left+output_pad_right;\n" +" const int channe_out_idx=channel_idx >> 2;\n" +" const int offset=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" const int dst_offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width+w_idx+output_pad_left)*16+(channel_idx % 4)*4;\n" +" \n" +" float4 in0=convert_float4(vload4(0,input0+offset*isFull.x));\n" +" float4 in1=convert_float4(vload4(0,input1+offset*isFull.y));\n" +" if(isFull.x == 0) {\n" +" in0=(float4)(in0.x,in0.x,in0.x,in0.x);\n" +" }\n" +" if(isFull.y == 0) {\n" +" in1=(float4)(in1.x,in1.x,in1.x,in1.x);\n" +" }\n" +" float4 out=OPERATOR;\n" +" if(activationType == 1) {\n" +" out=fmax(out,(float4)0);\n" +" }\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+dst_offset);\n" +" if(w_idx == 0){\n" +" int pad_offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width)*16+(channel_idx % 4)*4;\n" +" for(int i=0; i= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int channel16=(shape.w+15)/16;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" const int src_width=shape.z+input1_pad_left+input1_pad_right;\n" +" const int channe_out_idx=channel_idx >> 2;\n" +" const int offset0=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" const int offset1=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*src_width+w_idx+input1_pad_left)*16+(channel_idx % 4)*4;\n" +" float4 in0=convert_float4(vload4(0,input0+offset0*isFull.x));\n" +" float4 in1=convert_float4(vload4(0,input1+offset1*isFull.y));\n" +" if(isFull.x == 0) {\n" +" in0=(float4)(in0.x,in0.x,in0.x,in0.x);\n" +" }\n" +" if(isFull.y == 0) {\n" +" in1=(float4)(in1.x,in1.x,in1.x,in1.x);\n" +" }\n" +" float4 out=OPERATOR;\n" +" if(activationType == 1) {\n" +" out=fmax(out,(float4)0);\n" +" }\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+offset0);\n" +"}\n" +"__kernel void binary_buf_c16_c4_c4(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __global INPUT_TYPE* input0,__global INPUT_TYPE* input1,__global OUTPUT_TYPE* output,\n" +" __private const int4 shape,//[N,H,W,C]\n" +" __private const int2 isFull,\n" +" __private const int activationType,\n" +" __private const int input0_pad_left,__private const int input0_pad_right,\n" +" __private const int input1_pad_left,__private const int input1_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" if (get_global_id(0) >= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int channel16=(shape.w+15)/16;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" const int src_width=shape.z+input0_pad_left+input0_pad_right;\n" +" const int channe_out_idx=channel_idx >> 2;\n" +" const int offset1=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" const int offset0=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*src_width+w_idx+input0_pad_left)*16+(channel_idx % 4)*4;\n" +" \n" +" float4 in0=convert_float4(vload4(0,input0+offset0*isFull.x));\n" +" float4 in1=convert_float4(vload4(0,input1+offset1*isFull.y));\n" +" if(isFull.x == 0) {\n" +" in0=(float4)(in0.x,in0.x,in0.x,in0.x);\n" +" }\n" +" if(isFull.y == 0) {\n" +" in1=(float4)(in1.x,in1.x,in1.x,in1.x);\n" +" }\n" +" float4 out=OPERATOR;\n" +" \n" +" if(activationType == 1) {\n" +" out=fmax(out,(float4)0);\n" +" }\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+offset1);\n" +"}\n" +"__kernel void binary_buf_c4_c16_c16(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __global INPUT_TYPE* input0,__global INPUT_TYPE* input1,__global OUTPUT_TYPE* output,\n" +" __private const int4 shape,//[N,H,W,C]\n" +" __private const int2 isFull,\n" +" __private const int activationType,\n" +" __private const int input0_pad_left,__private const int input0_pad_right,\n" +" __private const int input1_pad_left,__private const int input1_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" if (get_global_id(0) >= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int channel16=(shape.w+15)/16;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" const int src_width=shape.z+input1_pad_left+input1_pad_right;\n" +" const int dst_width=shape.z+output_pad_left+output_pad_right;\n" +" const int channe_out_idx=channel_idx >> 2;\n" +" const int offset0=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" const int offset1=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*src_width+w_idx+input1_pad_left)*16+(channel_idx % 4)*4;\n" +" const int dst_offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width+w_idx+output_pad_left)*16+(channel_idx % 4)*4;\n" +" \n" +" float4 in0=convert_float4(vload4(0,input0+offset0*isFull.x));\n" +" float4 in1=convert_float4(vload4(0,input1+offset1*isFull.y));\n" +" if(isFull.x == 0) {\n" +" in0=(float4)(in0.x,in0.x,in0.x,in0.x);\n" +" }\n" +" if(isFull.y == 0) {\n" +" in1=(float4)(in1.x,in1.x,in1.x,in1.x);\n" +" }\n" +" float4 out=OPERATOR;\n" +" \n" +" if(activationType == 1) {\n" +" out=fmax(out,(float4)0);\n" +" }\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+dst_offset);\n" +" if(w_idx == 0){\n" +" int pad_offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width)*16+(channel_idx % 4)*4;\n" +" for(int i=0; i= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int channel16=(shape.w+15)/16;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" const int src_width=shape.z+input0_pad_left+input0_pad_right;\n" +" const int dst_width=shape.z+output_pad_left+output_pad_right;\n" +" const int channe_out_idx=channel_idx >> 2;\n" +" const int offset1=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" const int offset0=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*src_width+w_idx+input0_pad_left)*16+(channel_idx % 4)*4;\n" +" const int dst_offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width+w_idx+output_pad_left)*16+(channel_idx % 4)*4;\n" +" \n" +" float4 in0=convert_float4(vload4(0,input0+offset0*isFull.x));\n" +" float4 in1=convert_float4(vload4(0,input1+offset1*isFull.y));\n" +" if(isFull.x == 0) {\n" +" in0=(float4)(in0.x,in0.x,in0.x,in0.x);\n" +" }\n" +" if(isFull.y == 0) {\n" +" in1=(float4)(in1.x,in1.x,in1.x,in1.x);\n" +" }\n" +" float4 out=OPERATOR;\n" +" \n" +" if(activationType == 1) {\n" +" out=fmax(out,(float4)0);\n" +" }\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+dst_offset);\n" +" if(w_idx == 0){\n" +" int pad_offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width)*16+(channel_idx % 4)*4;\n" +" for(int i=0; i= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" \n" +" const int offset0=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" const int offset1=channel_idx*4;\n" +" \n" +" float4 in0=convert_float4(vload4(0,input0+offset0));\n" +" float4 in1=convert_float4(vload4(0,input1+offset1));\n" +" float4 out=OPERATOR;\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+offset0);\n" +"}\n" +"__kernel void prelu_buf_c4_c16(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __global INPUT_TYPE* input0,__global INPUT_TYPE* input1,__global OUTPUT_TYPE* output,\n" +" __private const int4 shape,//[N,H,W,C]\n" +" __private const int input0_pad_left,__private const int input0_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right\n" +" ) {\n" +" if (get_global_id(0) >= global_dim0 || get_global_id(1) >= global_dim1 || get_global_id(2) >= global_dim2) \n" +" return;\n" +" const int channel4=(shape.w+3)/4;\n" +" const int channel16=(shape.w+15)/16;\n" +" const int w_idx=get_global_id(0) % shape.z;\n" +" const int h_idx=get_global_id(0)/shape.z;\n" +" const int batch_idx=get_global_id(2);\n" +" const int channel_idx=get_global_id(1);\n" +" const int dst_width=shape.z+output_pad_left+output_pad_right;\n" +" const int channe_out_idx=channel_idx >> 2;\n" +" \n" +" const int offset0=(((batch_idx*channel4+channel_idx)*shape.y+h_idx)*shape.z+w_idx)*4;\n" +" const int offset1=channel_idx*4;\n" +" const int offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width+w_idx+output_pad_left)*16+(channel_idx % 4)*4;\n" +" float4 in0=convert_float4(vload4(0,input0+offset0));\n" +" float4 in1=convert_float4(vload4(0,input1+offset1));\n" +" float4 out=OPERATOR;\n" +" \n" +" vstore4(CONVERT_OUTPUT4(out),0,output+offset);\n" +" if(w_idx == 0){\n" +" int pad_offset=(((batch_idx*channel16+channe_out_idx)*shape.y+h_idx)*dst_width)*16+(channel_idx % 4)*4;\n" +" for(int i=0; ishape.z) {\n" +" for (int i=0; ishape.z ? (shape.z % 4) : 4;\n" +" for (int i=0; ishape.z) {\n" +" for (int i=0; ishape.z ? (shape.z % 4) : 4;\n" +" for (int i=0; i= inputHeight)\n" +" continue;\n" +" for(int j=0; j= inputHeight)\n" +" continue;\n" +" for(int j=0; j= inputHeight)\n" +" continue;\n" +" for(int j=0; j= inputHeight)\n" +" continue;\n" +" for(int j=0; j= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void interp(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,__write_only image2d_t output,\n" +" __private const float height_scale,__private const float width_scale,\n" +" __private const float height_offset,__private const float width_offset,\n" +" __private const int input_height,__private const int input_width,\n" +" __private const int out_height) {\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" const int output_channel_block_idxs=global_size_dim0;\n" +" const int output_width=global_size_dim1;\n" +" const int output_batch_idx=output_batch_height_block_idx/out_height;\n" +" const int output_height_idx=output_batch_height_block_idx % out_height;\n" +" const float scale_height=output_height_idx*height_scale+height_offset;\n" +" const float scale_width=output_width_block_idx*width_scale+width_offset;\n" +"#ifdef USE_ROUND\n" +" const int height_lf=min(max(0,(int)floor(scale_height+0.499f)),input_height-1);\n" +" const int width_lf=min(max(0,(int)floor(scale_width+0.499f)),input_width-1);\n" +"#else\n" +" const int height_lf=min(max(0,(int)floor(scale_height)),input_height-1);\n" +" const int width_lf=min(max(0,(int)floor(scale_width)),input_width-1);\n" +"#endif\n" +" const int input_width_offset=mul24(output_channel_block_idx,input_width);\n" +" const int input_height_offset=mul24(output_batch_idx,input_height);\n" +" float4 out =\n" +" read_imagef(input,SAMPLER,(int2)(input_width_offset+width_lf,input_height_offset+height_lf));\n" +" const int out_image_w=mad24(output_channel_block_idx,output_width,output_width_block_idx);\n" +" const int out_image_h=mad24(output_batch_idx,out_height,output_height_idx);\n" +" write_imagef(output,(int2)(out_image_w,out_image_h),out);\n" +"}\n" +"__kernel void interp3D(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,__write_only image2d_t output,\n" +" __private const float depth_scale,__private const float height_scale,__private const float width_scale,\n" +" __private const float depth_offset,__private const float height_offset,__private const float width_offset,\n" +" __private const int input_depth,__private const int input_height,__private const int input_width,\n" +" __private const int out_depth,__private const int out_height) {\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_height_width_block_idx=get_global_id(1);\n" +" const int output_batch_depth_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_height_width_block_idx,output_batch_depth_block_idx);\n" +" const int output_channel_block_idxs=global_size_dim0;\n" +" const int output_tensor_height_width=global_size_dim1;\n" +" const int out_width=output_tensor_height_width/out_height;\n" +" const int output_batch_idx=output_batch_depth_block_idx/out_depth;\n" +" const int output_depth_idx=output_batch_depth_block_idx % out_depth;\n" +" const int output_height_idx=output_height_width_block_idx/out_height;\n" +" const int output_width_idx=output_height_width_block_idx % out_height;\n" +" const float scale_depth=output_depth_idx*depth_scale+depth_offset;\n" +" const float scale_height=output_height_idx*height_scale+height_offset;\n" +" const float scale_width=output_width_idx*width_scale+width_offset;\n" +" const int depth_lf=max(0,(int)floor(scale_depth));\n" +" const int height_lf=max(0,(int)floor(scale_height));\n" +" const int width_lf=max(0,(int)floor(scale_width));\n" +" const int input_tensor_width_height=mul24(input_width,input_height);\n" +" const int input_image_width_offset=mul24(output_channel_block_idx,input_tensor_width_height);\n" +" const int input_image_height_offset=mul24(output_batch_idx,input_depth);\n" +" float4 out=read_imagef(input,SAMPLER,\n" +" (int2)(input_image_width_offset+input_width*(height_offset+height_lf)+width_lf+width_offset,\n" +" input_image_height_offset+depth_lf+depth_offset));\n" +" const int output_image_width_offset=output_channel_block_idx*output_tensor_height_width;\n" +" const int output_image_height_offset=output_batch_idx*out_depth;\n" +" // TODO: out\n" +" const int out_image_w=output_image_width_offset+output_height_idx*out_width+output_width_idx;\n" +" const int out_image_h=output_image_height_offset+output_batch_idx*out_depth+output_depth_idx;\n" +" write_imagef(output,(int2)(out_image_w,out_image_h),out);\n" +"}\n" +; #ifndef MNN_OPENCL_BUFFER_CLOSED #ifdef MNN_SUPPORT_INTEL_SUBGROUP -{ - "pooling_subgroup_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x6f,0x6f,0x6c,0x69,0x6e,0x67,0x5f,0x63,0x34,0x5f,0x63,0x34,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x59,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2b,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x34,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x41,0x44,0x44,0x49,0x4e,0x47,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x28,0x6d,0x69,0x6e,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x28,0x6d,0x69,0x6e,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x2d,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x3d,0x30,0x3b,0x20,0x6b,0x68,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x3d,0x30,0x3b,0x20,0x6b,0x77,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x6b,0x68,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x6b,0x77,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x3b,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x41,0x44,0x44,0x49,0x4e,0x47,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2b,0x2b,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x2a,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2b,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x3d,0x30,0x3b,0x20,0x6b,0x68,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x3d,0x30,0x3b,0x20,0x6b,0x77,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x6b,0x68,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x6b,0x77,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x20,0x3e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3f,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x29,0x20,0x3a,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x72,0x65,0x64,0x69,0x63,0x65,0x29,0x2c,0x20,0x20,0x30,0x2c,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x6f,0x6f,0x6c,0x69,0x6e,0x67,0x5f,0x63,0x34,0x5f,0x63,0x31,0x36,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x59,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2b,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x34,0x3b,0xa,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x41,0x44,0x44,0x49,0x4e,0x47,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x28,0x6d,0x69,0x6e,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x28,0x6d,0x69,0x6e,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x2d,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x3d,0x30,0x3b,0x20,0x6b,0x68,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x3d,0x30,0x3b,0x20,0x6b,0x77,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x6b,0x68,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x6b,0x77,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x3b,0xa,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x41,0x44,0x44,0x49,0x4e,0x47,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2b,0x2b,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x2a,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2b,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x3d,0x30,0x3b,0x20,0x6b,0x68,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x3d,0x30,0x3b,0x20,0x6b,0x77,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x77,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x6b,0x68,0x2a,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x6b,0x77,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x20,0x3e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3f,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x29,0x20,0x3a,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x28,0x63,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x2f,0x34,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x31,0x36,0x20,0x2b,0x20,0x63,0x5f,0x6c,0x65,0x66,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x72,0x65,0x64,0x69,0x63,0x65,0x29,0x2c,0x20,0x20,0x30,0x2c,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x2f,0x34,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x30,0x29,0x2a,0x31,0x36,0x20,0x2b,0x20,0x63,0x5f,0x6c,0x65,0x66,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x6f,0x6f,0x6c,0x69,0x6e,0x67,0x5f,0x63,0x31,0x36,0x5f,0x63,0x31,0x36,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3c,0x3c,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x59,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x32,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x33,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x34,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x35,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x36,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x37,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x41,0x44,0x44,0x49,0x4e,0x47,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x77,0x5f,0x73,0x69,0x7a,0x65,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x66,0x6d,0x69,0x6e,0x28,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x2d,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x6d,0x69,0x6e,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x77,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x77,0x5f,0x65,0x6e,0x64,0x20,0x3d,0x20,0x66,0x6d,0x69,0x6e,0x28,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x28,0x66,0x6c,0x6f,0x61,0x74,0x29,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x5f,0x65,0x6e,0x64,0x20,0x3d,0x20,0x66,0x6d,0x69,0x6e,0x28,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x28,0x77,0x5f,0x65,0x6e,0x64,0x20,0x2d,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x68,0x5f,0x65,0x6e,0x64,0x20,0x2d,0x20,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x38,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x38,0x29,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x62,0x5f,0x69,0x64,0x78,0x2c,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0x63,0x5f,0x69,0x64,0x78,0x29,0x2c,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2c,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2c,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x3d,0x30,0x3b,0x20,0x6b,0x68,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x69,0x29,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x7b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x5f,0x75,0x73,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x69,0x29,0x2c,0x31,0x36,0x29,0x29,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x69,0x29,0x2c,0x31,0x36,0x29,0x29,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x7b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x3d,0x30,0x3b,0x20,0x6b,0x77,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x73,0x72,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x38,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x72,0x63,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x6b,0x77,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2a,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x73,0x72,0x63,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x73,0x72,0x63,0x20,0x3e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3f,0x20,0x28,0x69,0x6e,0x74,0x38,0x29,0x28,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x29,0x20,0x3a,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2c,0x20,0x73,0x72,0x63,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2f,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x30,0x29,0x2a,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x2a,0x31,0x36,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x20,0x2a,0x20,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x70,0x61,0x64,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x2a,0x31,0x36,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x31,0x36,0x3b,0xa,0x23,0x69,0x66,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x4c,0x45,0x46,0x54,0x4f,0x56,0x45,0x52,0x53,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x63,0x5f,0x69,0x64,0x78,0x2a,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x26,0x26,0x20,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x38,0x20,0x3c,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x7b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x75,0x73,0x38,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x73,0x68,0x6f,0x72,0x74,0x38,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x77,0x72,0x69,0x74,0x65,0x38,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x38,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x25,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x73,0x67,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x34,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0x23,0x69,0x66,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x4c,0x45,0x46,0x54,0x4f,0x56,0x45,0x52,0x53,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x63,0x5f,0x69,0x64,0x78,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x26,0x26,0x20,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x5b,0x72,0x65,0x64,0x69,0x63,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x20,0x26,0x26,0x20,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x5b,0x72,0x65,0x64,0x69,0x63,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x72,0x65,0x71,0x64,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x29,0x29,0x29,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x6f,0x6f,0x6c,0x69,0x6e,0x67,0x5f,0x63,0x31,0x36,0x5f,0x63,0x34,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x20,0x3c,0x3c,0x20,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x5f,0x6f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x59,0x2c,0x20,0x2d,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x72,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x32,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x33,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x34,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x35,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x36,0x2c,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x20,0x2a,0x20,0x37,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x41,0x44,0x44,0x49,0x4e,0x47,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x77,0x5f,0x73,0x69,0x7a,0x65,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x66,0x6d,0x69,0x6e,0x28,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x20,0x2d,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x6d,0x69,0x6e,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x70,0x61,0x64,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x2d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x77,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x77,0x5f,0x65,0x6e,0x64,0x20,0x3d,0x20,0x66,0x6d,0x69,0x6e,0x28,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x28,0x66,0x6c,0x6f,0x61,0x74,0x29,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x5f,0x65,0x6e,0x64,0x20,0x3d,0x20,0x66,0x6d,0x69,0x6e,0x28,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x2c,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x20,0x3d,0x20,0x28,0x77,0x5f,0x65,0x6e,0x64,0x20,0x2d,0x20,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x68,0x5f,0x65,0x6e,0x64,0x20,0x2d,0x20,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x38,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x38,0x29,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x62,0x5f,0x69,0x64,0x78,0x2c,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x2c,0x63,0x5f,0x69,0x64,0x78,0x29,0x2c,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2c,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2c,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2c,0x31,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x3d,0x30,0x3b,0x20,0x6b,0x68,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x59,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x69,0x29,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x28,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0x7b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x61,0x73,0x5f,0x68,0x61,0x6c,0x66,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x5f,0x75,0x73,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x69,0x29,0x2c,0x31,0x36,0x29,0x29,0x29,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x28,0x69,0x6e,0x74,0x65,0x6c,0x5f,0x73,0x75,0x62,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x72,0x65,0x61,0x64,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x73,0x72,0x63,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x69,0x29,0x2c,0x31,0x36,0x29,0x29,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x7b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x3d,0x30,0x3b,0x20,0x6b,0x77,0x3c,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x5f,0x58,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x38,0x20,0x73,0x72,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x6f,0x70,0x65,0x6e,0x63,0x6c,0x5f,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x5f,0x68,0x69,0x6e,0x74,0x28,0x38,0x29,0x29,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x72,0x63,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x6c,0x69,0x6e,0x65,0x5f,0x63,0x61,0x63,0x68,0x65,0x5b,0x6b,0x77,0x20,0x2b,0x20,0x53,0x54,0x52,0x49,0x44,0x45,0x5f,0x58,0x2a,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x73,0x72,0x63,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x20,0x3d,0x20,0x73,0x72,0x63,0x20,0x3e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3f,0x20,0x28,0x69,0x6e,0x74,0x38,0x29,0x28,0x28,0x69,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x29,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x69,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x77,0x29,0x20,0x3a,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2c,0x20,0x73,0x72,0x63,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x50,0x4f,0x4f,0x4c,0x5f,0x41,0x56,0x47,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2f,0x20,0x74,0x6f,0x74,0x61,0x6c,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x73,0x67,0x6c,0x69,0x64,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x34,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x70,0x61,0x64,0x5f,0x6c,0x65,0x66,0x74,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2a,0x20,0x34,0x3b,0xa,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x6f,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x34,0x29,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x77,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x4c,0x45,0x46,0x54,0x4f,0x56,0x45,0x52,0x53,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x29,0x2a,0x31,0x36,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x63,0x5f,0x69,0x64,0x78,0x2a,0x31,0x36,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x20,0x26,0x26,0x20,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x5b,0x72,0x65,0x64,0x69,0x63,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x38,0x20,0x26,0x26,0x20,0x28,0x6f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x29,0x20,0x3c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x69,0x66,0x20,0x52,0x45,0x54,0x55,0x52,0x4e,0x5f,0x52,0x45,0x44,0x49,0x43,0x45,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x4f,0x75,0x74,0x70,0x75,0x74,0x5b,0x72,0x65,0x64,0x69,0x63,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x6c,0x69,0x64,0x5f,0x78,0x5d,0x20,0x3d,0x20,0x72,0x65,0x64,0x69,0x63,0x65,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, +const char* pooling_subgroup_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void pooling_c4_c4(GLOBAL_SIZE_3_DIMS __global const FLOAT *input,\n" +" __private const int2 input_shape,\n" +" __private const int2 output_shape,\n" +" __private const int2 pad_shape,\n" +" __global FLOAT *output,\n" +" __global FLOAT *rediceOutput,\n" +" __private const int channel,\n" +" __private const int in_channel_block,\n" +" __private const int out_channel_block,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right) {\n" +" \n" +" const int ow_idx=get_global_id(0);\n" +" const int b_oh_idx=get_global_id(1);\n" +" const int c_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(ow_idx,b_oh_idx,c_idx);\n" +" \n" +" const int b_idx=b_oh_idx/output_shape.x;\n" +" const int oh_idx=b_oh_idx % output_shape.x;\n" +" const int iw_start=mad24(ow_idx,STRIDE_X,-pad_shape.y);\n" +" const int ih_start=mad24(oh_idx,STRIDE_Y,-pad_shape.x);\n" +" \n" +" #ifdef POOL_AVG\n" +" COMPUTE_FLOAT4 result=(COMPUTE_FLOAT4)(0);\n" +" const int inp_offset=(((b_idx*in_channel_block+c_idx)*input_shape.x+ih_start)*input_shape.y+iw_start+input_pad_left)*4;\n" +"#ifdef COUNT_INCLUDE_PADDING\n" +" int total_count=(min(ih_start+KERNEL_Y,input_shape.x+pad_shape.x)-ih_start)*(min(iw_start+KERNEL_X,input_shape.y+pad_shape.y)-iw_start);\n" +"#else\n" +" int total_count=0;\n" +"#endif\n" +" for(int kh=0; kh= input_shape.x) {\n" +" continue;\n" +" }\n" +" for(int kw=0; kw= input_shape.y) {\n" +" continue;\n" +" }\n" +" COMPUTE_FLOAT4 inp_data=CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset+(kh*input_shape.y+kw)*4));\n" +" result += inp_data;\n" +"#ifndef COUNT_INCLUDE_PADDING\n" +" total_count++;\n" +"#endif\n" +" }\n" +" }\n" +" result=result/(COMPUTE_FLOAT4)(1.0*total_count);\n" +" #else\n" +" COMPUTE_FLOAT4 result=(COMPUTE_FLOAT4)(-FLT_MAX);\n" +" #if RETURN_REDICE\n" +" int4 redice=(int4)0;\n" +" #endif\n" +" const int inp_offset=(((b_idx*in_channel_block+c_idx)*input_shape.x+ih_start)*input_shape.y+iw_start+input_pad_left)*4;\n" +" for(int kh=0; kh= input_shape.x) {\n" +" continue;\n" +" }\n" +" for(int kw=0; kw= input_shape.y) {\n" +" continue;\n" +" }\n" +" COMPUTE_FLOAT4 inp_data=CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset+(kh*input_shape.y+kw)*4));\n" +" #if RETURN_REDICE\n" +" redice=inp_data>result ? (int4)((ih_start+kh)*input_shape.y+iw_start+kw) : redice;\n" +" #endif\n" +" result=fmax(result,inp_data);\n" +" }\n" +" }\n" +" #endif\n" +" \n" +" const int out_offset=(((b_idx*in_channel_block+c_idx)*output_shape.x+oh_idx)* output_shape.y+ow_idx+output_pad_left)*4;\n" +" vstore4(CONVERT_FLOAT4(result),0,output+out_offset);\n" +" #if RETURN_REDICE\n" +" vstore4(CONVERT_FLOAT4(redice),0,rediceOutput+(((b_idx*in_channel_block+c_idx)*output_shape.x+oh_idx)* output_shape.y+ow_idx)*4);\n" +" #endif\n" +"}\n" +"__kernel void pooling_c4_c16(GLOBAL_SIZE_3_DIMS __global const FLOAT *input,\n" +" __private const int2 input_shape,\n" +" __private const int2 output_shape,\n" +" __private const int2 pad_shape,\n" +" __global FLOAT *output,\n" +" __global FLOAT *rediceOutput,\n" +" __private const int channel,\n" +" __private const int in_channel_block,\n" +" __private const int out_channel_block,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right) {\n" +" \n" +" const int ow_idx=get_global_id(0);\n" +" const int b_oh_idx=get_global_id(1);\n" +" const int c_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(ow_idx,b_oh_idx,c_idx);\n" +" \n" +" const int b_idx=b_oh_idx/output_shape.x;\n" +" const int oh_idx=b_oh_idx % output_shape.x;\n" +" const int iw_start=mad24(ow_idx,STRIDE_X,-pad_shape.y);\n" +" const int ih_start=mad24(oh_idx,STRIDE_Y,-pad_shape.x);\n" +" const int dst_width=output_shape.y+output_pad_left+output_pad_right;\n" +" \n" +" #ifdef POOL_AVG\n" +" COMPUTE_FLOAT4 result=(COMPUTE_FLOAT4)(0);\n" +" const int inp_offset=(((b_idx*in_channel_block+c_idx)*input_shape.x+ih_start)*input_shape.y+iw_start+input_pad_left)*4;\n" +" #ifdef COUNT_INCLUDE_PADDING\n" +" int total_count=(min(ih_start+KERNEL_Y,input_shape.x+pad_shape.x)-ih_start)*(min(iw_start+KERNEL_X,input_shape.y+pad_shape.y)-iw_start);\n" +"#else\n" +" int total_count=0;\n" +"#endif\n" +" for(int kh=0; kh= input_shape.x) {\n" +" continue;\n" +" }\n" +" for(int kw=0; kw= input_shape.y) {\n" +" continue;\n" +" }\n" +" COMPUTE_FLOAT4 inp_data=CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset+(kh*input_shape.y+kw)*4));\n" +" result += inp_data;\n" +"#ifndef COUNT_INCLUDE_PADDING\n" +" total_count++;\n" +"#endif\n" +" }\n" +" }\n" +" result=result/(COMPUTE_FLOAT4)(1.0*total_count);\n" +" #else\n" +" COMPUTE_FLOAT4 result=(COMPUTE_FLOAT4)(-FLT_MAX);\n" +" #if RETURN_REDICE\n" +" int4 redice=(int4)0;\n" +" #endif\n" +" const int inp_offset=(((b_idx*in_channel_block+c_idx)*input_shape.x+ih_start)*input_shape.y+iw_start+input_pad_left)*4;\n" +" for(int kh=0; kh= input_shape.x) {\n" +" continue;\n" +" }\n" +" for(int kw=0; kw= input_shape.y) {\n" +" continue;\n" +" }\n" +" COMPUTE_FLOAT4 inp_data=CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset+(kh*input_shape.y+kw)*4));\n" +" #if RETURN_REDICE\n" +" redice=inp_data>result ? (int4)((ih_start+kh)*input_shape.y+iw_start+kw) : redice;\n" +" #endif\n" +" result=fmax(result,inp_data);\n" +" }\n" +" }\n" +" #endif\n" +" const int c_left=(c_idx % 4)*4;\n" +" const int out_offset=(((b_idx*out_channel_block+c_idx/4)*output_shape.x+oh_idx)* dst_width+ow_idx+output_pad_left)*16+c_left;\n" +" vstore4(CONVERT_FLOAT4(result),0,output+out_offset);\n" +" #if RETURN_REDICE\n" +" vstore4(CONVERT_FLOAT4(redice),0,rediceOutput+(((b_idx*out_channel_block+c_idx)*output_shape.x+oh_idx)* output_shape.y+ow_idx)*4);\n" +" #endif\n" +" if(ow_idx == 0){\n" +" int pad_offset=(((b_idx*out_channel_block+c_idx/4)*output_shape.x+oh_idx)* dst_width+0)*16+c_left;\n" +" for(int i=0; i= input_shape.x) {\n" +" continue;\n" +" }\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" for (int i=0; i= 0 && (iw_start+i)result ? (int8)((ih_start+kh)*input_shape.y+iw_start+kw) : redice;\n" +"#endif\n" +" result=fmax(result,src);\n" +"#endif\n" +" }\n" +" }\n" +"#ifdef POOL_AVG\n" +" result=result/total_count;\n" +"#endif\n" +" if(ow_idx == 0){\n" +" int pad_offset=(((b_idx*out_channel_block+c_idx)*output_shape.x+oh_idx)* dst_width+0)*16+sglid;\n" +" for(int i=0; i= channel) {\n" +" for (int i=0; i<8; i++) {\n" +" if ((c_idx*16+sglid= channel) {\n" +" for (int i=0; i<8; i++) {\n" +" if ((c_idx*16+lid_y*4+lid_x= input_shape.x) {\n" +" continue;\n" +" }\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" for (int i=0; i= 0 && (iw_start+i)result ? (int8)((ih_start+kh)*input_shape.y+iw_start+kw) : redice;\n" +"#endif\n" +" result=fmax(result,src);\n" +"#endif\n" +" }\n" +" }\n" +"#ifdef POOL_AVG\n" +" result=result/total_count;\n" +"#endif\n" +" const uint lid_x=sglid % 4;\n" +" const uint lid_y=sglid/4;\n" +" \n" +" const int out_offset=(((b_idx*out_channel_block+c_idx*4)*output_shape.x+oh_idx)* output_shape.y+ow_idx+output_pad_left)*4;\n" +" const int width_height=output_shape.y*output_shape.x*4;\n" +"#if RETURN_REDICE\n" +" const int redice_offset=(((b_idx*out_channel_block+c_idx*4)*output_shape.x+oh_idx)* output_shape.y+ow_idx)*4;\n" +"#endif\n" +"#if OUTPUT_LEFTOVERS\n" +" if ((c_idx+1)*16 >= channel) {\n" +" for (int i=0; i<8; i++) {\n" +" if ((c_idx*16+lid_y*4+lid_x= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void pooling(GLOBAL_SIZE_3_DIMS __global const FLOAT *input,\n" +" __private const int2 input_shape,\n" +" __private const int2 output_shape,\n" +" __private const int2 pad_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 kernel_shape,\n" +" __global FLOAT *output,\n" +" __global FLOAT *rediceOutput,\n" +" __private const int channel_block) {\n" +" \n" +" const int ow_idx=get_global_id(0);\n" +" const int b_oh_idx=get_global_id(1);\n" +" const int c_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(ow_idx,b_oh_idx,c_idx);\n" +" \n" +" const int b_idx=b_oh_idx/output_shape.x;\n" +" const int oh_idx=b_oh_idx % output_shape.x;\n" +" const int iw_start=mad24(ow_idx,stride_shape.y,-pad_shape.y);\n" +" const int ih_start=mad24(oh_idx,stride_shape.x,-pad_shape.x);\n" +" \n" +" #ifdef POOL_AVG\n" +" COMPUTE_FLOAT4 result=(COMPUTE_FLOAT4)(0);\n" +" const int inp_offset=(((b_idx*channel_block+c_idx)*input_shape.x+ih_start)*input_shape.y+iw_start)*4;\n" +" #ifdef COUNT_INCLUDE_PADDING\n" +" int total_count=(min(ih_start+kernel_shape.x,input_shape.x+pad_shape.x)-ih_start)*(min(iw_start+kernel_shape.y,input_shape.y+pad_shape.y)-iw_start);\n" +" #else\n" +" int total_count=0;\n" +" #endif\n" +" for(int kh=0; kh= input_shape.x) {\n" +" continue;\n" +" }\n" +" for(int kw=0; kw= input_shape.y) {\n" +" continue;\n" +" }\n" +" COMPUTE_FLOAT4 inp_data=CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset+(kh*input_shape.y+kw)*4));\n" +" result += inp_data;\n" +" #ifndef COUNT_INCLUDE_PADDING\n" +" total_count++;\n" +" #endif\n" +" }\n" +" }\n" +" result=result/(COMPUTE_FLOAT4)(1.0*total_count);\n" +" #else\n" +" COMPUTE_FLOAT4 result=(COMPUTE_FLOAT4)(-FLT_MAX);\n" +" #if RETURN_REDICE\n" +" int4 redice=(int4)0;\n" +" #endif\n" +" const int inp_offset=(((b_idx*channel_block+c_idx)*input_shape.x+ih_start)*input_shape.y+iw_start)*4;\n" +" for(int kh=0; kh= input_shape.x) {\n" +" continue;\n" +" }\n" +" for(int kw=0; kw= input_shape.y) {\n" +" continue;\n" +" }\n" +" COMPUTE_FLOAT4 inp_data=CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset+(kh*input_shape.y+kw)*4));\n" +" #if RETURN_REDICE\n" +" redice=inp_data>result ? (int4)((ih_start+kh)*input_shape.y+iw_start+kw) : redice;\n" +" #endif\n" +" result=fmax(result,inp_data);\n" +" }\n" +" }\n" +" #endif\n" +" \n" +" const int out_offset=(((b_idx*channel_block+c_idx)*output_shape.x+oh_idx)* output_shape.y+ow_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(result),0,output+out_offset);\n" +" #if RETURN_REDICE\n" +" vstore4(CONVERT_FLOAT4(redice),0,rediceOutput+out_offset);\n" +" #endif\n" +"}\n" +"#ifdef LOCAL_SIZE\n" +"__kernel void global_pooling_buf(GLOBAL_SIZE_3_DIMS __global const FLOAT *input,\n" +" __private const int2 input_shape,\n" +" __private const int2 output_shape,\n" +" __private const int2 pad_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 kernel_shape,\n" +" __global FLOAT *output,\n" +" __global FLOAT *rediceOutput,\n" +" __private const int channel_block) {\n" +" const int local_id=get_local_id(0);\n" +" const int output_channel_idx=get_global_id(1);\n" +" const int output_batch_idx=get_global_id(2);\n" +"#ifdef POOL_AVG\n" +" COMPUTE_FLOAT4 output_result=0;\n" +"#else\n" +" COMPUTE_FLOAT4 output_result=(COMPUTE_FLOAT4)(-FLT_MAX);\n" +"#if RETURN_REDICE\n" +" int4 redice=(int4)0;\n" +" int4 local rediceId[LOCAL_SIZE];\n" +"#endif\n" +"#endif\n" +" COMPUTE_FLOAT4 local sum[LOCAL_SIZE];\n" +" const int inp_offset=((output_batch_idx*channel_block+output_channel_idx)*input_shape.x)*input_shape.y*4;\n" +" const int size=input_shape.x*input_shape.y;\n" +" for(int i=local_id; ioutput_result ? (int4)(i) : redice;\n" +"#endif\n" +"#endif\n" +" }\n" +" \n" +" sum[local_id]=output_result;\n" +"#if RETURN_REDICE\n" +" rediceId[local_id]=redice;\n" +"#endif\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" for(int i=LOCAL_SIZE/2; i>0; i /= 2){\n" +" if (local_idsum[local_id+i] ? rediceId[local_id] : rediceId[local_id+i];\n" +"#endif\n" +" }\n" +"#endif\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" }\n" +" output_result=sum[0];\n" +"#ifdef POOL_AVG\n" +" output_result /= (input_shape.x*input_shape.y);\n" +"#endif\n" +" const int out_offset=(output_batch_idx*channel_block+output_channel_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(output_result),0,output+out_offset);\n" +"#if RETURN_REDICE\n" +" redice=rediceId[0];\n" +" vstore4(CONVERT_FLOAT4(redice),0,rediceOutput+out_offset);\n" +"#endif\n" +"}\n" +"#endif\n" +; #endif -{ - "winogradTransformSource2_5_1", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x77,0x69,0x6e,0x6f,0x67,0x72,0x61,0x64,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x53,0x6f,0x75,0x72,0x63,0x65,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x30,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x33,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x58,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x59,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2f,0x2f,0x20,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2a,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x58,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x70,0x6f,0x73,0x2e,0x79,0x2c,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x28,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x32,0x20,0x2d,0x20,0x70,0x61,0x64,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x28,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x32,0x20,0x2d,0x20,0x70,0x61,0x64,0x59,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x34,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x35,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x34,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x35,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x34,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x35,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x34,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x35,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x34,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x35,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x34,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x35,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x34,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x35,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x34,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x35,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x34,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x35,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x34,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x35,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x34,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x34,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x34,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x34,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x34,0x34,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x35,0x34,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x34,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x35,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x20,0x3d,0x20,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x2c,0x20,0x2d,0x31,0x2c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x35,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x69,0x6d,0x61,0x67,0x65,0x53,0x78,0x2c,0x20,0x69,0x6d,0x61,0x67,0x65,0x53,0x79,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x30,0x20,0x3d,0x20,0x2b,0x53,0x30,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x30,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x30,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x30,0x20,0x3d,0x20,0x2b,0x53,0x31,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x31,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x30,0x20,0x3d,0x20,0x2b,0x53,0x32,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x32,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x32,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x30,0x20,0x3d,0x20,0x2b,0x53,0x33,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x33,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x33,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x34,0x30,0x20,0x3d,0x20,0x2b,0x53,0x34,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x34,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x34,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x35,0x30,0x20,0x3d,0x20,0x2b,0x53,0x35,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x35,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x53,0x35,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x34,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x35,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x34,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x35,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x33,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x30,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x33,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x33,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x32,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x33,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x33,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x34,0x33,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x34,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x34,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x35,0x33,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x35,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x35,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x34,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x30,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x30,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x34,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x31,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x34,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x32,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x32,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x34,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x33,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x33,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x34,0x34,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x34,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x34,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x34,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x35,0x34,0x20,0x3d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x35,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x53,0x35,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x53,0x35,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x35,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x53,0x30,0x33,0x20,0x2b,0x20,0x53,0x30,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x35,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x53,0x31,0x33,0x20,0x2b,0x20,0x53,0x31,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x35,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x53,0x32,0x33,0x20,0x2b,0x20,0x53,0x32,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x35,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x53,0x33,0x33,0x20,0x2b,0x20,0x53,0x33,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x34,0x35,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x53,0x34,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x53,0x34,0x33,0x20,0x2b,0x20,0x53,0x34,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x35,0x35,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x53,0x35,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x53,0x35,0x33,0x20,0x2b,0x20,0x53,0x35,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x30,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x32,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x34,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x34,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x35,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x33,0x30,0x20,0x2b,0x20,0x6d,0x35,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x36,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x34,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x37,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x38,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x39,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x30,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x31,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x33,0x31,0x20,0x2b,0x20,0x6d,0x35,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x32,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x32,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x34,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x33,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x34,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x35,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x36,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x37,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x33,0x32,0x20,0x2b,0x20,0x6d,0x35,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x38,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x32,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x34,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x31,0x39,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x30,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x31,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x32,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x33,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x33,0x33,0x20,0x2b,0x20,0x6d,0x35,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x34,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x32,0x34,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x34,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x35,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x34,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x36,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x34,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x34,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x37,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x34,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x34,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x38,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x34,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x32,0x39,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x31,0x34,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x33,0x34,0x20,0x2b,0x20,0x6d,0x35,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x30,0x29,0x2c,0x20,0x2b,0x6d,0x30,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x31,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x32,0x35,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x32,0x35,0x20,0x2a,0x20,0x6d,0x34,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x31,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x35,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x32,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x31,0x35,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x36,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x35,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x33,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x31,0x36,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x33,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x35,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x35,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x34,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x31,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x32,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x38,0x33,0x33,0x33,0x33,0x33,0x20,0x2a,0x20,0x6d,0x33,0x35,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x34,0x31,0x36,0x36,0x36,0x37,0x20,0x2a,0x20,0x6d,0x34,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x64,0x73,0x74,0x58,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x33,0x35,0x29,0x2c,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x34,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x31,0x35,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x35,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x33,0x35,0x20,0x2b,0x20,0x6d,0x35,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, +const char* winogradTransformSource2_5_1 = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void winogradTransformSource(__read_only image2d_t uInput,// 0\n" +" __write_only image2d_t uOutput,__private const int unitWidth,\n" +" __private const int unitHeight,// 3\n" +" __private const int padX,__private const int padY,\n" +" __private const int srcWidth,// 6\n" +" __private const int srcHeight,__private const int srcChannelC4,\n" +" __private const int batchOffset) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1)); \n" +" if (pos.x= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S00=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S10=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S20=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S30=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=4+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S40=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=5+sxStart;\n" +" int sy=0+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S50=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S01=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S11=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S21=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S31=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=4+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S41=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=5+sxStart;\n" +" int sy=1+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S51=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S02=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S12=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S22=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S32=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=4+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S42=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=5+sxStart;\n" +" int sy=2+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S52=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S03=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S13=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S23=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S33=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=4+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S43=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=5+sxStart;\n" +" int sy=3+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S53=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=4+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S04=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=4+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S14=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=4+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S24=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=4+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S34=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=4+sxStart;\n" +" int sy=4+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S44=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=5+sxStart;\n" +" int sy=4+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S54=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=5+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S05=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=5+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S15=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=5+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S25=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=5+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S35=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=4+sxStart;\n" +" int sy=5+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S45=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" {\n" +" int sx=5+sxStart;\n" +" int sy=5+syStart;\n" +" int imageSx=select(sx+pos.y*srcWidth,-1,sx<0 || sx >= srcWidth);\n" +" int imageSy=select(batchOffset*srcHeight+sy,-1,sy<0 || sy >= srcHeight);\n" +" S55=RI_F(uInput,SAMPLER,(int2)(imageSx,imageSy));\n" +" }\n" +" FLOAT4 m00=+S00-(FLOAT)1.25*S02+(FLOAT)0.25*S04;\n" +" FLOAT4 m10=+S10-(FLOAT)1.25*S12+(FLOAT)0.25*S14;\n" +" FLOAT4 m20=+S20-(FLOAT)1.25*S22+(FLOAT)0.25*S24;\n" +" FLOAT4 m30=+S30-(FLOAT)1.25*S32+(FLOAT)0.25*S34;\n" +" FLOAT4 m40=+S40-(FLOAT)1.25*S42+(FLOAT)0.25*S44;\n" +" FLOAT4 m50=+S50-(FLOAT)1.25*S52+(FLOAT)0.25*S54;\n" +" FLOAT4 m01=+(FLOAT)0.666667*S01+(FLOAT)0.666667*S02-(FLOAT)0.166667*S03-(FLOAT)0.166667*S04;\n" +" FLOAT4 m11=+(FLOAT)0.666667*S11+(FLOAT)0.666667*S12-(FLOAT)0.166667*S13-(FLOAT)0.166667*S14;\n" +" FLOAT4 m21=+(FLOAT)0.666667*S21+(FLOAT)0.666667*S22-(FLOAT)0.166667*S23-(FLOAT)0.166667*S24;\n" +" FLOAT4 m31=+(FLOAT)0.666667*S31+(FLOAT)0.666667*S32-(FLOAT)0.166667*S33-(FLOAT)0.166667*S34;\n" +" FLOAT4 m41=+(FLOAT)0.666667*S41+(FLOAT)0.666667*S42-(FLOAT)0.166667*S43-(FLOAT)0.166667*S44;\n" +" FLOAT4 m51=+(FLOAT)0.666667*S51+(FLOAT)0.666667*S52-(FLOAT)0.166667*S53-(FLOAT)0.166667*S54;\n" +" FLOAT4 m02=-(FLOAT)0.666667*S01+(FLOAT)0.666667*S02+(FLOAT)0.166667*S03-(FLOAT)0.166667*S04;\n" +" FLOAT4 m12=-(FLOAT)0.666667*S11+(FLOAT)0.666667*S12+(FLOAT)0.166667*S13-(FLOAT)0.166667*S14;\n" +" FLOAT4 m22=-(FLOAT)0.666667*S21+(FLOAT)0.666667*S22+(FLOAT)0.166667*S23-(FLOAT)0.166667*S24;\n" +" FLOAT4 m32=-(FLOAT)0.666667*S31+(FLOAT)0.666667*S32+(FLOAT)0.166667*S33-(FLOAT)0.166667*S34;\n" +" FLOAT4 m42=-(FLOAT)0.666667*S41+(FLOAT)0.666667*S42+(FLOAT)0.166667*S43-(FLOAT)0.166667*S44;\n" +" FLOAT4 m52=-(FLOAT)0.666667*S51+(FLOAT)0.666667*S52+(FLOAT)0.166667*S53-(FLOAT)0.166667*S54;\n" +" FLOAT4 m03 =\n" +" -(FLOAT)0.0833333*S01-(FLOAT)0.0416667*S02+(FLOAT)0.0833333*S03+(FLOAT)0.0416667*S04;\n" +" FLOAT4 m13 =\n" +" -(FLOAT)0.0833333*S11-(FLOAT)0.0416667*S12+(FLOAT)0.0833333*S13+(FLOAT)0.0416667*S14;\n" +" FLOAT4 m23 =\n" +" -(FLOAT)0.0833333*S21-(FLOAT)0.0416667*S22+(FLOAT)0.0833333*S23+(FLOAT)0.0416667*S24;\n" +" FLOAT4 m33 =\n" +" -(FLOAT)0.0833333*S31-(FLOAT)0.0416667*S32+(FLOAT)0.0833333*S33+(FLOAT)0.0416667*S34;\n" +" FLOAT4 m43 =\n" +" -(FLOAT)0.0833333*S41-(FLOAT)0.0416667*S42+(FLOAT)0.0833333*S43+(FLOAT)0.0416667*S44;\n" +" FLOAT4 m53 =\n" +" -(FLOAT)0.0833333*S51-(FLOAT)0.0416667*S52+(FLOAT)0.0833333*S53+(FLOAT)0.0416667*S54;\n" +" FLOAT4 m04 =\n" +" +(FLOAT)0.0833333*S01-(FLOAT)0.0416667*S02-(FLOAT)0.0833333*S03+(FLOAT)0.0416667*S04;\n" +" FLOAT4 m14 =\n" +" +(FLOAT)0.0833333*S11-(FLOAT)0.0416667*S12-(FLOAT)0.0833333*S13+(FLOAT)0.0416667*S14;\n" +" FLOAT4 m24 =\n" +" +(FLOAT)0.0833333*S21-(FLOAT)0.0416667*S22-(FLOAT)0.0833333*S23+(FLOAT)0.0416667*S24;\n" +" FLOAT4 m34 =\n" +" +(FLOAT)0.0833333*S31-(FLOAT)0.0416667*S32-(FLOAT)0.0833333*S33+(FLOAT)0.0416667*S34;\n" +" FLOAT4 m44 =\n" +" +(FLOAT)0.0833333*S41-(FLOAT)0.0416667*S42-(FLOAT)0.0833333*S43+(FLOAT)0.0416667*S44;\n" +" FLOAT4 m54 =\n" +" +(FLOAT)0.0833333*S51-(FLOAT)0.0416667*S52-(FLOAT)0.0833333*S53+(FLOAT)0.0416667*S54;\n" +" FLOAT4 m05=+(FLOAT)4.0*S01-(FLOAT)5.0*S03+S05;\n" +" FLOAT4 m15=+(FLOAT)4.0*S11-(FLOAT)5.0*S13+S15;\n" +" FLOAT4 m25=+(FLOAT)4.0*S21-(FLOAT)5.0*S23+S25;\n" +" FLOAT4 m35=+(FLOAT)4.0*S31-(FLOAT)5.0*S33+S35;\n" +" FLOAT4 m45=+(FLOAT)4.0*S41-(FLOAT)5.0*S43+S45;\n" +" FLOAT4 m55=+(FLOAT)4.0*S51-(FLOAT)5.0*S53+S55;\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*0),+m00-(FLOAT)1.25*m20+(FLOAT)0.25*m40);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*1),\n" +" +(FLOAT)0.666667*m10+(FLOAT)0.666667*m20-(FLOAT)0.166667*m30-(FLOAT)0.166667*m40);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*2),\n" +" -(FLOAT)0.666667*m10+(FLOAT)0.666667*m20+(FLOAT)0.166667*m30-(FLOAT)0.166667*m40);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*3),\n" +" -(FLOAT)0.0833333*m10-(FLOAT)0.0416667*m20+(FLOAT)0.0833333*m30+(FLOAT)0.0416667*m40);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*4),\n" +" +(FLOAT)0.0833333*m10-(FLOAT)0.0416667*m20-(FLOAT)0.0833333*m30+(FLOAT)0.0416667*m40);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*5),+(FLOAT)4.0*m10-(FLOAT)5.0*m30+m50);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*6),+m01-(FLOAT)1.25*m21+(FLOAT)0.25*m41);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*7),\n" +" +(FLOAT)0.666667*m11+(FLOAT)0.666667*m21-(FLOAT)0.166667*m31-(FLOAT)0.166667*m41);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*8),\n" +" -(FLOAT)0.666667*m11+(FLOAT)0.666667*m21+(FLOAT)0.166667*m31-(FLOAT)0.166667*m41);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*9),\n" +" -(FLOAT)0.0833333*m11-(FLOAT)0.0416667*m21+(FLOAT)0.0833333*m31+(FLOAT)0.0416667*m41);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*10),\n" +" +(FLOAT)0.0833333*m11-(FLOAT)0.0416667*m21-(FLOAT)0.0833333*m31+(FLOAT)0.0416667*m41);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*11),+(FLOAT)4.0*m11-(FLOAT)5.0*m31+m51);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*12),+m02-(FLOAT)1.25*m22+(FLOAT)0.25*m42);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*13),\n" +" +(FLOAT)0.666667*m12+(FLOAT)0.666667*m22-(FLOAT)0.166667*m32-(FLOAT)0.166667*m42);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*14),\n" +" -(FLOAT)0.666667*m12+(FLOAT)0.666667*m22+(FLOAT)0.166667*m32-(FLOAT)0.166667*m42);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*15),\n" +" -(FLOAT)0.0833333*m12-(FLOAT)0.0416667*m22+(FLOAT)0.0833333*m32+(FLOAT)0.0416667*m42);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*16),\n" +" +(FLOAT)0.0833333*m12-(FLOAT)0.0416667*m22-(FLOAT)0.0833333*m32+(FLOAT)0.0416667*m42);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*17),+(FLOAT)4.0*m12-(FLOAT)5.0*m32+m52);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*18),+m03-(FLOAT)1.25*m23+(FLOAT)0.25*m43);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*19),\n" +" +(FLOAT)0.666667*m13+(FLOAT)0.666667*m23-(FLOAT)0.166667*m33-(FLOAT)0.166667*m43);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*20),\n" +" -(FLOAT)0.666667*m13+(FLOAT)0.666667*m23+(FLOAT)0.166667*m33-(FLOAT)0.166667*m43);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*21),\n" +" -(FLOAT)0.0833333*m13-(FLOAT)0.0416667*m23+(FLOAT)0.0833333*m33+(FLOAT)0.0416667*m43);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*22),\n" +" +(FLOAT)0.0833333*m13-(FLOAT)0.0416667*m23-(FLOAT)0.0833333*m33+(FLOAT)0.0416667*m43);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*23),+(FLOAT)4.0*m13-(FLOAT)5.0*m33+m53);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*24),+m04-(FLOAT)1.25*m24+(FLOAT)0.25*m44);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*25),\n" +" +(FLOAT)0.666667*m14+(FLOAT)0.666667*m24-(FLOAT)0.166667*m34-(FLOAT)0.166667*m44);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*26),\n" +" -(FLOAT)0.666667*m14+(FLOAT)0.666667*m24+(FLOAT)0.166667*m34-(FLOAT)0.166667*m44);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*27),\n" +" -(FLOAT)0.0833333*m14-(FLOAT)0.0416667*m24+(FLOAT)0.0833333*m34+(FLOAT)0.0416667*m44);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*28),\n" +" +(FLOAT)0.0833333*m14-(FLOAT)0.0416667*m24-(FLOAT)0.0833333*m34+(FLOAT)0.0416667*m44);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*29),+(FLOAT)4.0*m14-(FLOAT)5.0*m34+m54);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*30),+m05-(FLOAT)1.25*m25+(FLOAT)0.25*m45);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*31),\n" +" +(FLOAT)0.666667*m15+(FLOAT)0.666667*m25-(FLOAT)0.166667*m35-(FLOAT)0.166667*m45);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*32),\n" +" -(FLOAT)0.666667*m15+(FLOAT)0.666667*m25+(FLOAT)0.166667*m35-(FLOAT)0.166667*m45);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*33),\n" +" -(FLOAT)0.0833333*m15-(FLOAT)0.0416667*m25+(FLOAT)0.0833333*m35+(FLOAT)0.0416667*m45);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*34),\n" +" +(FLOAT)0.0833333*m15-(FLOAT)0.0416667*m25-(FLOAT)0.0833333*m35+(FLOAT)0.0416667*m45);\n" +" WI_F(uOutput,(int2)(dstX,unitHeight_idx+unitHeight*35),+(FLOAT)4.0*m15-(FLOAT)5.0*m35+m55);\n" +" }\n" +" }\n" +"}\n" +; #ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "unary_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x67,0x65,0x6c,0x75,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x30,0x2e,0x37,0x39,0x37,0x38,0x38,0x34,0x35,0x38,0x66,0x20,0x2a,0x20,0x28,0x30,0x2e,0x30,0x34,0x34,0x37,0x31,0x35,0x66,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2b,0x20,0x69,0x6e,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x78,0x32,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x64,0x73,0x74,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3e,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x35,0x2e,0x30,0x66,0x20,0x3f,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x31,0x2e,0x30,0x66,0x20,0x3a,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x20,0x3c,0x3d,0x20,0x2d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x35,0x2e,0x30,0x66,0x20,0x3f,0x20,0x2d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x31,0x2e,0x30,0x66,0x20,0x3a,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x20,0x2a,0x20,0x28,0x31,0x33,0x35,0x31,0x33,0x35,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x31,0x37,0x33,0x32,0x35,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x33,0x37,0x38,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x29,0x29,0x29,0x29,0x20,0x2f,0x20,0x28,0x31,0x33,0x35,0x31,0x33,0x35,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x36,0x32,0x33,0x37,0x30,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x28,0x33,0x31,0x35,0x30,0x2e,0x30,0x66,0x20,0x2b,0x20,0x78,0x32,0x20,0x2a,0x20,0x32,0x38,0x2e,0x30,0x66,0x29,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x31,0x2e,0x30,0x66,0x20,0x2b,0x20,0x64,0x73,0x74,0x29,0x20,0x2a,0x20,0x69,0x6e,0x20,0x2a,0x20,0x30,0x2e,0x35,0x66,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x75,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x62,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x77,0x2c,0x20,0x68,0x62,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x68,0x62,0x20,0x2f,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x68,0x62,0x20,0x25,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2b,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x2b,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2b,0x77,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x20,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x7d,0xa,0xa, } - }, +const char* unary_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"inline float4 gelu(float4 in){\n" +" float4 value=0.79788458f*(0.044715f*in*in*in+in);\n" +" float4 x2=value*value;\n" +" float4 dst=value>(float4)5.0f ? (float4)1.0f : (value <= -(float4)5.0f ? -(float4)1.0f :\n" +" (value*(135135.0f+x2*(17325.0f+x2*(378.0f+x2))))/(135135.0f+x2*(62370.0f+x2*(3150.0f+x2*28.0f))));\n" +" return (1.0f+dst)*in*0.5f;\n" +"}\n" +"__kernel void unary_buf(GLOBAL_SIZE_3_DIMS\n" +" __global const INPUT_TYPE *input,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int height) {\n" +" const int channel_block_idx=get_global_id(0);\n" +" const int w=get_global_id(1);\n" +" const int hb=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(channel_block_idx,w,hb);\n" +" const int batch_idx=hb/height;\n" +" const int height_idx=hb % height;\n" +" const int offset=(((batch_idx*global_size_dim0+channel_block_idx)*height+height_idx)*global_size_dim1+w)*4;\n" +" float4 in=convert_float4(vload4(0,input+offset));\n" +" float4 out=OPERATOR;\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+offset);\n" +"}\n" +; #endif #ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "depthwise_conv2d_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x57,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x4e,0x45,0x58,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x43,0x41,0x4c,0x28,0x78,0x2c,0x79,0x29,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x78,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x78,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x78,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x79,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x79,0x29,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x79,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x79,0x29,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x63,0x34,0x68,0x31,0x77,0x34,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x78,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x29,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x6b,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3d,0x20,0x6b,0x77,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x2b,0x31,0x2a,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x2b,0x32,0x2a,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x2b,0x33,0x2a,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x31,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x5d,0x20,0x78,0x20,0x6f,0x63,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x49,0x64,0x78,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x69,0x6e,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x49,0x64,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0x2c,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x63,0x34,0x68,0x31,0x77,0x32,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x78,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x29,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x6b,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3d,0x20,0x6b,0x77,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x2b,0x31,0x2a,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x31,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x5d,0x20,0x78,0x20,0x6f,0x63,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x49,0x64,0x78,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x69,0x6e,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x49,0x64,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x63,0x34,0x68,0x31,0x77,0x31,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x78,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x29,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x6b,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3d,0x20,0x6b,0x77,0x20,0x2a,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x5f,0x64,0x69,0x6c,0x61,0x74,0x65,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x31,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x5d,0x20,0x78,0x20,0x6f,0x63,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x49,0x64,0x78,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x69,0x6e,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x49,0x64,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x73,0x31,0x5f,0x63,0x38,0x68,0x31,0x77,0x34,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2b,0x30,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x33,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x78,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x29,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x2b,0x30,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x6b,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x36,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x37,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x31,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x5d,0x20,0x78,0x20,0x6f,0x63,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x49,0x64,0x78,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x69,0x6e,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x49,0x64,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x2b,0x30,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x34,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x35,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x36,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x37,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0x2c,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x37,0x29,0x2c,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x36,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x73,0x31,0x5f,0x63,0x38,0x68,0x31,0x77,0x32,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2b,0x30,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x31,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x78,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x29,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x2b,0x30,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x6b,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x30,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x63,0x31,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x31,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x5d,0x20,0x78,0x20,0x6f,0x63,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x49,0x64,0x78,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x69,0x6e,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x49,0x64,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x2b,0x30,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x2b,0x31,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x34,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x35,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x5f,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2a,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x35,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x34,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x73,0x31,0x5f,0x63,0x34,0x68,0x31,0x77,0x34,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x34,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x2b,0x20,0x33,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x68,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x68,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x78,0x3b,0x20,0x6b,0x68,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x6b,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x29,0x20,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x63,0x75,0x72,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x77,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x77,0x20,0x3c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x3b,0x20,0x6b,0x77,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x68,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x6b,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x31,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x32,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x33,0x2b,0x6b,0x77,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6b,0x77,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x53,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x31,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x73,0x5d,0x20,0x78,0x20,0x6f,0x63,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x49,0x64,0x78,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x69,0x6e,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x42,0x6c,0x6f,0x63,0x6b,0x49,0x64,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x34,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x34,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0x2c,0x20,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x6b,0x33,0x73,0x31,0x70,0x31,0x5f,0x63,0x34,0x68,0x31,0x77,0x32,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x32,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x66,0x69,0x72,0x73,0x74,0x20,0x6c,0x69,0x6e,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3c,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x73,0x65,0x63,0x6f,0x6e,0x64,0x20,0x6c,0x69,0x6e,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3c,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x74,0x68,0x69,0x72,0x64,0x20,0x6c,0x69,0x6e,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x20,0x3c,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x5f,0x30,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x32,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x32,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x32,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0xa,0x76,0x6f,0x69,0x64,0x20,0x64,0x65,0x70,0x74,0x68,0x77,0x69,0x73,0x65,0x5f,0x63,0x6f,0x6e,0x76,0x32,0x64,0x5f,0x6b,0x33,0x73,0x31,0x70,0x31,0x5f,0x63,0x34,0x68,0x32,0x77,0x32,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x62,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6c,0x61,0x74,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x68,0x77,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x63,0x2f,0x34,0x20,0x2a,0x20,0x6f,0x77,0x2f,0x32,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x62,0x20,0x2a,0x20,0x68,0x2f,0x32,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x3d,0x20,0x28,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x31,0x29,0x20,0x2f,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x63,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x62,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x63,0x5f,0x69,0x64,0x78,0x2c,0x20,0x62,0x69,0x61,0x73,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x68,0x32,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x5f,0x69,0x64,0x78,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x32,0x5f,0x69,0x64,0x78,0x20,0x2d,0x20,0x70,0x61,0x64,0x5f,0x68,0x77,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x66,0x69,0x72,0x73,0x74,0x20,0x6c,0x69,0x6e,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x73,0x65,0x63,0x6f,0x6e,0x64,0x20,0x6c,0x69,0x6e,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x44,0x57,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x4e,0x45,0x58,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x43,0x41,0x4c,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x31,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x74,0x68,0x69,0x72,0x64,0x20,0x6c,0x69,0x6e,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x32,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x44,0x57,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x4e,0x45,0x58,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x43,0x41,0x4c,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x32,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x32,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x32,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x68,0x77,0x2e,0x79,0x2c,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2b,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x77,0x65,0x69,0x67,0x68,0x74,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x66,0x6f,0x72,0x74,0x68,0x20,0x6c,0x69,0x6e,0x65,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x20,0x3c,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x33,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x33,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x33,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x69,0x6e,0x5f,0x68,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x78,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x5f,0x77,0x5f,0x73,0x74,0x61,0x72,0x74,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x20,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x29,0x20,0x3f,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x33,0x2a,0x69,0x6e,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x44,0x57,0x5f,0x43,0x4f,0x4e,0x56,0x5f,0x4e,0x45,0x58,0x54,0x5f,0x4c,0x49,0x4e,0x45,0x5f,0x43,0x41,0x4c,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x36,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x5f,0x69,0x64,0x78,0x2a,0x63,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x63,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x68,0x32,0x5f,0x69,0x64,0x78,0x29,0x2a,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x77,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x77,0x32,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x68,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x78,0x20,0x2d,0x20,0x6f,0x75,0x74,0x5f,0x68,0x32,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x77,0x20,0x3e,0x3d,0x20,0x32,0x20,0x26,0x26,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x68,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x77,0x20,0x3d,0x3d,0x20,0x31,0x20,0x20,0x26,0x26,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x68,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x32,0x29,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x68,0x77,0x2e,0x79,0x2b,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x77,0x20,0x3e,0x3d,0x20,0x32,0x20,0x20,0x26,0x26,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x68,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x31,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x56,0x61,0x6c,0x75,0x65,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, +const char* depthwise_conv2d_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"#define DW_CONV_NEXT_LINE_CAL(x,y) "" x = mad(inValue0, weights0, x); "" x = mad(inValue1, weights1, x); "" x = mad(inValue2, weights2, x); "" y = mad(inValue1, weights0, y); "" y = mad(inValue2, weights1, y); "" y=mad(inValue3,weights2,y);\n" +"__kernel\n" +"void depthwise_conv2d_c4h1w4(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/4\n" +" const int out_b_h_idx=get_global_id(1);// b*h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_hw.x;\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" COMPUTE_FLOAT4 outValue2=outValue0;\n" +" COMPUTE_FLOAT4 outValue3=outValue0;\n" +" const int out_w4_idx=out_w_idx << 2;\n" +" const int in_w_start_0=out_w4_idx*stride_hw.y-pad_hw.y;\n" +" const int in_w_start_1=in_w_start_0+stride_hw.y;\n" +" const int in_w_start_2=in_w_start_1+stride_hw.y;\n" +" const int in_w_start_3=in_w_start_2+stride_hw.y;\n" +" const int in_h_start=out_h_idx*stride_hw.x-pad_hw.x;\n" +" \n" +" for (int kh=0; kh= in_hw.x) continue;\n" +" \n" +" int inp_offset=(((b_idx*c_blocks+c_idx)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" for (int kw=0; kw= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw_dilate+0,input+inp_offset));\n" +" COMPUTE_FLOAT4 inValue1=(in_w_start_1+kw_dilate<0 || in_w_start_1+kw_dilate >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw_dilate+1*stride_hw.y,input+inp_offset));\n" +" COMPUTE_FLOAT4 inValue2=(in_w_start_2+kw_dilate<0 || in_w_start_2+kw_dilate >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw_dilate+2*stride_hw.y,input+inp_offset));\n" +" COMPUTE_FLOAT4 inValue3=(in_w_start_3+kw_dilate<0 || in_w_start_3+kw_dilate >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw_dilate+3*stride_hw.y,input+inp_offset));\n" +" //NC4HW4 [1,filterShape.x*filterShape.y,1,channelBlocks] x oc4\n" +" //index: [0,filterIdx,0,inChannelBlockIdx]\n" +" COMPUTE_FLOAT4 weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" outValue1=mad(inValue1,weights,outValue1);\n" +" outValue2=mad(inValue2,weights,outValue2);\n" +" outValue3=mad(inValue3,weights,outValue3);\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +" outValue1=fmax(outValue1,(COMPUTE_FLOAT4)0);\n" +" outValue2=fmax(outValue2,(COMPUTE_FLOAT4)0);\n" +" outValue3=fmax(outValue3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue1=clamp(outValue1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue2=clamp(outValue2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue3=clamp(outValue3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w4_idx)*4;\n" +" const int remain=out_hw.y-out_w4_idx;\n" +" if (remain >= 4) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),2,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue3),3,output+out_offset);\n" +" } else if (remain == 3) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),2,output+out_offset);\n" +" } else if (remain == 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" }\n" +" \n" +"}\n" +"__kernel\n" +"void depthwise_conv2d_c4h1w2(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/4\n" +" const int out_b_h_idx=get_global_id(1);// b*h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_hw.x;\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" const int out_w2_idx=out_w_idx << 1;\n" +" const int in_w_start_0=out_w2_idx*stride_hw.y-pad_hw.y;\n" +" const int in_w_start_1=in_w_start_0+stride_hw.y;\n" +" \n" +" const int in_h_start=out_h_idx*stride_hw.x-pad_hw.x;\n" +" \n" +" for (int kh=0; kh= in_hw.x) continue;\n" +" \n" +" int inp_offset=(((b_idx*c_blocks+c_idx)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" for (int kw=0; kw= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw_dilate+0,input+inp_offset));\n" +" COMPUTE_FLOAT4 inValue1=(in_w_start_1+kw_dilate<0 || in_w_start_1+kw_dilate >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw_dilate+1*stride_hw.y,input+inp_offset));\n" +" //NC4HW4 [1,filterShape.x*filterShape.y,1,channelBlocks] x oc4\n" +" //index: [0,filterIdx,0,inChannelBlockIdx]\n" +" COMPUTE_FLOAT4 weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" outValue1=mad(inValue1,weights,outValue1);\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +" outValue1=fmax(outValue1,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue1=clamp(outValue1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w2_idx)*4;\n" +" const int remain=out_hw.y-out_w2_idx;\n" +" if (remain >= 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" }\n" +" \n" +"}\n" +"__kernel\n" +"void depthwise_conv2d_c4h1w1(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/4\n" +" const int out_b_h_idx=get_global_id(1);// b*h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_hw.x;\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" const int in_w_start_0=out_w_idx*stride_hw.y-pad_hw.y;\n" +" const int in_h_start=out_h_idx*stride_hw.x-pad_hw.x;\n" +" \n" +" for (int kh=0; kh= in_hw.x) continue;\n" +" \n" +" int inp_offset=(((b_idx*c_blocks+c_idx)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" for (int kw=0; kw= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw_dilate+0,input+inp_offset));\n" +" //NC4HW4 [1,filterShape.x*filterShape.y,1,channelBlocks] x oc4\n" +" //index: [0,filterIdx,0,inChannelBlockIdx]\n" +" COMPUTE_FLOAT4 weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +"}\n" +"__kernel\n" +"void depthwise_conv2d_s1_c8h1w4(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/4\n" +" const int out_b_h_idx=get_global_id(1);// b*h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_hw.x;\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx+0,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" COMPUTE_FLOAT4 outValue2=outValue0;\n" +" COMPUTE_FLOAT4 outValue3=outValue0;\n" +" COMPUTE_FLOAT4 outValue4=CONVERT_COMPUTE_FLOAT4(vload4(c_idx+1,bias));\n" +" COMPUTE_FLOAT4 outValue5=outValue4;\n" +" COMPUTE_FLOAT4 outValue6=outValue4;\n" +" COMPUTE_FLOAT4 outValue7=outValue4;\n" +" const int out_w4_idx=out_w_idx << 2;\n" +" const int in_w_start_0=out_w4_idx-pad_hw.y;\n" +" const int in_w_start_1=in_w_start_0+1;\n" +" const int in_w_start_2=in_w_start_0+2;\n" +" const int in_w_start_3=in_w_start_0+3;\n" +" const int in_h_start=out_h_idx-pad_hw.x;\n" +" \n" +" for (int kh=0; kh= in_hw.x) continue;\n" +" \n" +" int inp_offset_c0=(((b_idx*c_blocks+c_idx+0)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" int inp_offset_c1=(((b_idx*c_blocks+c_idx+1)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" for (int kw=0; kw= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+0,input+inp_offset_c0));\n" +" COMPUTE_FLOAT4 inValue1=(in_w_start_1+kw<0 || in_w_start_1+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+1,input+inp_offset_c0));\n" +" COMPUTE_FLOAT4 inValue2=(in_w_start_2+kw<0 || in_w_start_2+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+2,input+inp_offset_c0));\n" +" COMPUTE_FLOAT4 inValue3=(in_w_start_3+kw<0 || in_w_start_3+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+3,input+inp_offset_c0));\n" +" COMPUTE_FLOAT4 inValue4=(in_w_start_0+kw<0 || in_w_start_0+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+0,input+inp_offset_c1));\n" +" COMPUTE_FLOAT4 inValue5=(in_w_start_1+kw<0 || in_w_start_1+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+1,input+inp_offset_c1));\n" +" COMPUTE_FLOAT4 inValue6=(in_w_start_2+kw<0 || in_w_start_2+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+2,input+inp_offset_c1));\n" +" COMPUTE_FLOAT4 inValue7=(in_w_start_3+kw<0 || in_w_start_3+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+3,input+inp_offset_c1));\n" +" \n" +" //NC4HW4 [1,filterShape.x*filterShape.y,1,channelBlocks] x oc4\n" +" //index: [0,filterIdx,0,inChannelBlockIdx]\n" +" COMPUTE_FLOAT4 weights_0=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx+0)*4));\n" +" COMPUTE_FLOAT4 weights_1=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx+1)*4));\n" +" outValue0=mad(inValue0,weights_0,outValue0);\n" +" outValue1=mad(inValue1,weights_0,outValue1);\n" +" outValue2=mad(inValue2,weights_0,outValue2);\n" +" outValue3=mad(inValue3,weights_0,outValue3);\n" +" \n" +" outValue4=mad(inValue4,weights_1,outValue4);\n" +" outValue5=mad(inValue5,weights_1,outValue5);\n" +" outValue6=mad(inValue6,weights_1,outValue6);\n" +" outValue7=mad(inValue7,weights_1,outValue7);\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +" outValue1=fmax(outValue1,(COMPUTE_FLOAT4)0);\n" +" outValue2=fmax(outValue2,(COMPUTE_FLOAT4)0);\n" +" outValue3=fmax(outValue3,(COMPUTE_FLOAT4)0);\n" +" \n" +" outValue4=fmax(outValue4,(COMPUTE_FLOAT4)0);\n" +" outValue5=fmax(outValue5,(COMPUTE_FLOAT4)0);\n" +" outValue6=fmax(outValue6,(COMPUTE_FLOAT4)0);\n" +" outValue7=fmax(outValue7,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue1=clamp(outValue1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue2=clamp(outValue2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue3=clamp(outValue3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" \n" +" outValue4=clamp(outValue4,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue5=clamp(outValue5,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue6=clamp(outValue6,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue7=clamp(outValue7,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w4_idx)*4;\n" +" const int remain=out_hw.y-out_w4_idx;\n" +" if (remain >= 4) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),2,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue3),3,output+out_offset);\n" +" } else if (remain == 3) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),2,output+out_offset);\n" +" } else if (remain == 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" }\n" +" \n" +" if(c_idx+1 >= c_blocks) return;\n" +" \n" +" out_offset += out_hw.x*out_hw.y*4;\n" +" if (remain >= 4) {\n" +" vstore4(CONVERT_FLOAT4(outValue4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue5),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue6),2,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue7),3,output+out_offset);\n" +" } else if (remain == 3) {\n" +" vstore4(CONVERT_FLOAT4(outValue4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue5),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue6),2,output+out_offset);\n" +" } else if (remain == 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue5),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue4),0,output+out_offset);\n" +" }\n" +"}\n" +"__kernel\n" +"void depthwise_conv2d_s1_c8h1w2(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/4\n" +" const int out_b_h_idx=get_global_id(1);// b*h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_hw.x;\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx+0,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" COMPUTE_FLOAT4 outValue4=CONVERT_COMPUTE_FLOAT4(vload4(c_idx+1,bias));\n" +" COMPUTE_FLOAT4 outValue5=outValue4;\n" +" const int out_w2_idx=out_w_idx << 1;\n" +" const int in_w_start_0=out_w2_idx-pad_hw.y;\n" +" const int in_w_start_1=in_w_start_0+1;\n" +" const int in_h_start=out_h_idx-pad_hw.x;\n" +" \n" +" for (int kh=0; kh= in_hw.x) continue;\n" +" \n" +" int inp_offset_c0=(((b_idx*c_blocks+c_idx+0)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" int inp_offset_c1=(((b_idx*c_blocks+c_idx+1)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" for (int kw=0; kw= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+0,input+inp_offset_c0));\n" +" COMPUTE_FLOAT4 inValue1=(in_w_start_1+kw<0 || in_w_start_1+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+1,input+inp_offset_c0));\n" +" COMPUTE_FLOAT4 inValue4=(in_w_start_0+kw<0 || in_w_start_0+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+0,input+inp_offset_c1));\n" +" COMPUTE_FLOAT4 inValue5=(in_w_start_1+kw<0 || in_w_start_1+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+1,input+inp_offset_c1));\n" +" //NC4HW4 [1,filterShape.x*filterShape.y,1,channelBlocks] x oc4\n" +" //index: [0,filterIdx,0,inChannelBlockIdx]\n" +" COMPUTE_FLOAT4 weights_0=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx+0)*4));\n" +" COMPUTE_FLOAT4 weights_1=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx+1)*4));\n" +" outValue0=mad(inValue0,weights_0,outValue0);\n" +" outValue1=mad(inValue1,weights_0,outValue1);\n" +" \n" +" outValue4=mad(inValue4,weights_1,outValue4);\n" +" outValue5=mad(inValue5,weights_1,outValue5);\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +" outValue1=fmax(outValue1,(COMPUTE_FLOAT4)0);\n" +" \n" +" outValue4=fmax(outValue4,(COMPUTE_FLOAT4)0);\n" +" outValue5=fmax(outValue5,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue1=clamp(outValue1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" \n" +" outValue4=clamp(outValue4,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue5=clamp(outValue5,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w2_idx)*4;\n" +" const int remain=out_hw.y-out_w2_idx;\n" +" if (remain >= 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" }\n" +" \n" +" if(c_idx+1 >= c_blocks) return;\n" +" \n" +" out_offset += out_hw.x*out_hw.y*4;\n" +" if (remain >= 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue5),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue4),0,output+out_offset);\n" +" }\n" +"}\n" +"__kernel\n" +"void depthwise_conv2d_s1_c4h1w4(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/4\n" +" const int out_b_h_idx=get_global_id(1);// b*h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_hw.x;\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" COMPUTE_FLOAT4 outValue2=outValue0;\n" +" COMPUTE_FLOAT4 outValue3=outValue0;\n" +" const int out_w4_idx=out_w_idx << 2;\n" +" const int in_w_start_0=out_w4_idx-pad_hw.y;\n" +" const int in_w_start_1=in_w_start_0+1;\n" +" const int in_w_start_2=in_w_start_0+2;\n" +" const int in_w_start_3=in_w_start_0+3;\n" +" const int in_h_start=out_h_idx-pad_hw.x;\n" +" \n" +" COMPUTE_FLOAT4 inValue0,inValue1,inValue2,inValue3;\n" +" for (int kh=0; kh= in_hw.x) continue;\n" +" \n" +" int inp_offset=(((b_idx*c_blocks+c_idx)*in_hw.x+in_h_cur)* in_hw.y+in_w_start_0)*4;\n" +" for (int kw=0; kw= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+0,input+inp_offset));\n" +" inValue1=(in_w_start_1+kw<0 || in_w_start_1+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+1,input+inp_offset));\n" +" inValue2=(in_w_start_2+kw<0 || in_w_start_2+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+2,input+inp_offset));\n" +" inValue3=(in_w_start_3+kw<0 || in_w_start_3+kw >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(kw+3,input+inp_offset));\n" +" //NC4HW4 [1,filterShape.x*filterShape.y,1,channelBlocks] x oc4\n" +" //index: [0,filterIdx,0,inChannelBlockIdx]\n" +" COMPUTE_FLOAT4 weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" outValue1=mad(inValue1,weights,outValue1);\n" +" outValue2=mad(inValue2,weights,outValue2);\n" +" outValue3=mad(inValue3,weights,outValue3);\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +" outValue1=fmax(outValue1,(COMPUTE_FLOAT4)0);\n" +" outValue2=fmax(outValue2,(COMPUTE_FLOAT4)0);\n" +" outValue3=fmax(outValue3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue1=clamp(outValue1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue2=clamp(outValue2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue3=clamp(outValue3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w4_idx)*4;\n" +" const int remain=out_hw.y-out_w4_idx;\n" +" if (remain >= 4) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),2,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue3),3,output+out_offset);\n" +" } else if (remain == 3) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),2,output+out_offset);\n" +" } else if (remain == 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" }\n" +"}\n" +"__kernel\n" +"void depthwise_conv2d_k3s1p1_c4h1w2(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/2\n" +" const int out_b_h_idx=get_global_id(1);// b*h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_hw.x;\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" const int out_w2_idx=out_w_idx << 1;\n" +" const int in_w_start_0=out_w2_idx-pad_hw.y;\n" +" const int in_h_start=out_h_idx-pad_hw.x;\n" +" COMPUTE_FLOAT4 inValue0,inValue1,inValue2,inValue3;\n" +" //first line\n" +" const int inp_offset=(((b_idx*c_blocks+c_idx)*in_hw.x+in_h_start)* in_hw.y+in_w_start_0)*4;\n" +" inValue0=(in_h_start<0 || in_w_start_0<0 ) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset));\n" +" inValue1=(in_h_start<0 || in_w_start_0+1 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(1,input+inp_offset));\n" +" inValue2=(in_h_start<0 || in_w_start_0+2 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2,input+inp_offset));\n" +" inValue3=(in_h_start<0 || in_w_start_0+3 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(3,input+inp_offset));\n" +" int filter_idx=mad24(0,filter_hw.y,0);\n" +" COMPUTE_FLOAT4 weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" outValue1=mad(inValue1,weights,outValue1);\n" +" filter_idx=mad24(0,filter_hw.y,1);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue1,weights,outValue0);\n" +" outValue1=mad(inValue2,weights,outValue1);\n" +" \n" +" filter_idx=mad24(0,filter_hw.y,2);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue2,weights,outValue0);\n" +" outValue1=mad(inValue3,weights,outValue1);\n" +" //second line\n" +" inValue0=(in_h_start+1 >= in_hw.x || in_w_start_0<0 ) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+0,input+inp_offset));\n" +" inValue1=(in_h_start+1 >= in_hw.x || in_w_start_0+1 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+1,input+inp_offset));\n" +" inValue2=(in_h_start+1 >= in_hw.x || in_w_start_0+2 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+2,input+inp_offset));\n" +" inValue3=(in_h_start+1 >= in_hw.x || in_w_start_0+3 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+3,input+inp_offset));\n" +" \n" +" filter_idx=mad24(1,filter_hw.y,0);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" outValue1=mad(inValue1,weights,outValue1);\n" +" filter_idx=mad24(1,filter_hw.y,1);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue1,weights,outValue0);\n" +" outValue1=mad(inValue2,weights,outValue1);\n" +" \n" +" filter_idx=mad24(1,filter_hw.y,2);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue2,weights,outValue0);\n" +" outValue1=mad(inValue3,weights,outValue1);\n" +" \n" +" //third line\n" +" inValue0=(in_h_start+2 >= in_hw.x || in_w_start_0<0 ) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+0,input+inp_offset));\n" +" inValue1=(in_h_start+2 >= in_hw.x || in_w_start_0+1 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+1,input+inp_offset));\n" +" inValue2=(in_h_start+2 >= in_hw.x || in_w_start_0+2 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+2,input+inp_offset));\n" +" inValue3=(in_h_start+2 >= in_hw.x || in_w_start_0+3 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+3,input+inp_offset));\n" +" \n" +" filter_idx=mad24(2,filter_hw.y,0);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" outValue1=mad(inValue1,weights,outValue1);\n" +" filter_idx=mad24(2,filter_hw.y,1);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue1,weights,outValue0);\n" +" outValue1=mad(inValue2,weights,outValue1);\n" +" \n" +" filter_idx=mad24(2,filter_hw.y,2);\n" +" weights=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue2,weights,outValue0);\n" +" outValue1=mad(inValue3,weights,outValue1);\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +" outValue1=fmax(outValue1,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue1=clamp(outValue1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w2_idx)*4;\n" +" const int remain=out_hw.y-out_w2_idx;\n" +" if (remain >= 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" }\n" +"}\n" +"__kernel\n" +"void depthwise_conv2d_k3s1p1_c4h2w2(GLOBAL_SIZE_2_DIMS __global const FLOAT *input,\n" +" __global const FLOAT *filter,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int channel,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int c_blocks) {\n" +" const int out_c_w_idx=get_global_id(0);// oc/4*ow/2\n" +" const int out_b_h_idx=get_global_id(1);// b*h/2\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_h_blocks=(out_hw.x+1)/2;\n" +" const int c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int b_idx=out_b_h_idx/out_h_blocks;\n" +" const int out_h_idx=out_b_h_idx % out_h_blocks;\n" +" COMPUTE_FLOAT4 outValue0=CONVERT_COMPUTE_FLOAT4(vload4(c_idx,bias));\n" +" COMPUTE_FLOAT4 outValue1=outValue0;\n" +" COMPUTE_FLOAT4 outValue2=outValue0;\n" +" COMPUTE_FLOAT4 outValue3=outValue0;\n" +" const int out_w2_idx=out_w_idx << 1;\n" +" const int in_w_start=out_w2_idx-pad_hw.y;\n" +" const int out_h2_idx=out_h_idx << 1;\n" +" const int in_h_start=out_h2_idx-pad_hw.x;\n" +" COMPUTE_FLOAT4 inValue0,inValue1,inValue2,inValue3;\n" +" //first line\n" +" const int inp_offset=(((b_idx*c_blocks+c_idx)*in_hw.x+in_h_start)* in_hw.y+in_w_start)*4;\n" +" inValue0=(in_h_start<0 || in_w_start<0 ) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(0,input+inp_offset));\n" +" inValue1=(in_h_start<0 || in_w_start+1 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(1,input+inp_offset));\n" +" inValue2=(in_h_start<0 || in_w_start+2 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2,input+inp_offset));\n" +" inValue3=(in_h_start<0 || in_w_start+3 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(3,input+inp_offset));\n" +" int filter_idx=mad24(0,filter_hw.y,0);\n" +" COMPUTE_FLOAT4 weights0=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights0,outValue0);\n" +" outValue1=mad(inValue1,weights0,outValue1);\n" +" filter_idx=mad24(0,filter_hw.y,1);\n" +" COMPUTE_FLOAT4 weights1=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue1,weights1,outValue0);\n" +" outValue1=mad(inValue2,weights1,outValue1);\n" +" \n" +" \n" +" filter_idx=mad24(0,filter_hw.y,2);\n" +" COMPUTE_FLOAT4 weights2=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue2,weights2,outValue0);\n" +" outValue1=mad(inValue3,weights2,outValue1);\n" +" //second line\n" +" inValue0=(in_h_start+1 >= in_hw.x || in_w_start<0 ) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+0,input+inp_offset));\n" +" inValue1=(in_h_start+1 >= in_hw.x || in_w_start+1 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+1,input+inp_offset));\n" +" inValue2=(in_h_start+1 >= in_hw.x || in_w_start+2 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+2,input+inp_offset));\n" +" inValue3=(in_h_start+1 >= in_hw.x || in_w_start+3 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_hw.y+3,input+inp_offset));\n" +" \n" +" DW_CONV_NEXT_LINE_CAL(outValue2,outValue3)\n" +" \n" +" filter_idx=mad24(1,filter_hw.y,0);\n" +" weights0=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights0,outValue0);\n" +" outValue1=mad(inValue1,weights0,outValue1);\n" +" filter_idx=mad24(1,filter_hw.y,1);\n" +" weights1=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue1,weights1,outValue0);\n" +" outValue1=mad(inValue2,weights1,outValue1);\n" +" \n" +" filter_idx=mad24(1,filter_hw.y,2);\n" +" weights2=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue2,weights2,outValue0);\n" +" outValue1=mad(inValue3,weights2,outValue1);\n" +" \n" +" //third line\n" +" inValue0=(in_h_start+2 >= in_hw.x || in_w_start<0 ) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+0,input+inp_offset));\n" +" inValue1=(in_h_start+2 >= in_hw.x || in_w_start+1 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+1,input+inp_offset));\n" +" inValue2=(in_h_start+2 >= in_hw.x || in_w_start+2 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+2,input+inp_offset));\n" +" inValue3=(in_h_start+2 >= in_hw.x || in_w_start+3 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(2*in_hw.y+3,input+inp_offset));\n" +" \n" +" DW_CONV_NEXT_LINE_CAL(outValue2,outValue3)\n" +" \n" +" filter_idx=mad24(2,filter_hw.y,0);\n" +" weights0=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue0,weights0,outValue0);\n" +" outValue1=mad(inValue1,weights0,outValue1);\n" +" filter_idx=mad24(2,filter_hw.y,1);\n" +" weights1=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue1,weights1,outValue0);\n" +" outValue1=mad(inValue2,weights1,outValue1);\n" +" \n" +" filter_idx=mad24(2,filter_hw.y,2);\n" +" weights2=CONVERT_COMPUTE_FLOAT4(vload4(0,filter+(filter_idx*c_blocks+c_idx)*4));\n" +" outValue0=mad(inValue2,weights2,outValue0);\n" +" outValue1=mad(inValue3,weights2,outValue1);\n" +" \n" +" //forth line\n" +" inValue0=(in_h_start+3 >= in_hw.x || in_w_start<0 ) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(3*in_hw.y+0,input+inp_offset));\n" +" inValue1=(in_h_start+3 >= in_hw.x || in_w_start+1 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(3*in_hw.y+1,input+inp_offset));\n" +" inValue2=(in_h_start+3 >= in_hw.x || in_w_start+2 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(3*in_hw.y+2,input+inp_offset));\n" +" inValue3=(in_h_start+3 >= in_hw.x || in_w_start+3 >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(3*in_hw.y+3,input+inp_offset));\n" +" \n" +" DW_CONV_NEXT_LINE_CAL(outValue2,outValue3)\n" +" \n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(COMPUTE_FLOAT4)0);\n" +" outValue1=fmax(outValue1,(COMPUTE_FLOAT4)0);\n" +" outValue2=fmax(outValue2,(COMPUTE_FLOAT4)0);\n" +" outValue3=fmax(outValue3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue1=clamp(outValue1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue2=clamp(outValue2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" outValue3=clamp(outValue3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((b_idx*c_blocks+c_idx)*out_hw.x+out_h2_idx)*out_hw.y+out_w2_idx)*4;\n" +" const int remain_w=out_hw.y-out_w2_idx;\n" +" const int remain_h=out_hw.x-out_h2_idx;\n" +" if(remain_w >= 2 && remain_h >= 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),out_hw.y+0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue3),out_hw.y+1,output+out_offset);\n" +" } else if(remain_w == 1 && remain_h >= 2) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue2),out_hw.y+0,output+out_offset);\n" +" } else if(remain_w >= 2 && remain_h == 1) {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(outValue1),1,output+out_offset);\n" +" } else {\n" +" vstore4(CONVERT_FLOAT4(outValue0),0,output+out_offset);\n" +" }\n" +"}\n" +; #endif #ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "winogradTransform_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x69,0x6e,0x64,0x65,0x78,0x30,0x2c,0x20,0x69,0x6e,0x64,0x65,0x78,0x31,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x64,0x65,0x78,0x30,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x64,0x65,0x78,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x77,0x69,0x6e,0x6f,0x54,0x72,0x61,0x6e,0x73,0x53,0x72,0x63,0x42,0x75,0x66,0x32,0x5f,0x33,0x5f,0x31,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x30,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x33,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x58,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x64,0x59,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2f,0x2f,0x20,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x20,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x70,0x6f,0x73,0x2e,0x78,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x61,0x6c,0x50,0x6f,0x73,0x20,0x20,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2f,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x5a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x25,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x59,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x3d,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x20,0x3d,0x20,0x28,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x59,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x64,0x73,0x74,0x59,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x58,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x64,0x73,0x74,0x59,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x25,0x20,0x34,0x20,0x2b,0x20,0x34,0x20,0x2a,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x74,0x63,0x68,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x28,0x72,0x65,0x61,0x6c,0x50,0x6f,0x73,0x2e,0x78,0x29,0x20,0x2a,0x20,0x32,0x20,0x2d,0x20,0x70,0x61,0x64,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x28,0x72,0x65,0x61,0x6c,0x50,0x6f,0x73,0x2e,0x79,0x29,0x20,0x2a,0x20,0x32,0x20,0x2d,0x20,0x70,0x61,0x64,0x59,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x49,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x73,0x72,0x63,0x5a,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x32,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x30,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x31,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x31,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x32,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x32,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x78,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x79,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x33,0x20,0x2b,0x20,0x73,0x79,0x53,0x74,0x61,0x72,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3d,0x20,0x28,0x73,0x78,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x78,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x73,0x79,0x20,0x3e,0x3d,0x20,0x73,0x72,0x63,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x33,0x33,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x42,0x6f,0x75,0x6e,0x64,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x2b,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x30,0x20,0x3d,0x20,0x2b,0x53,0x30,0x30,0x20,0x2d,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x30,0x20,0x3d,0x20,0x2b,0x53,0x31,0x30,0x20,0x2d,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x30,0x20,0x3d,0x20,0x2b,0x53,0x32,0x30,0x20,0x2d,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x30,0x20,0x3d,0x20,0x2b,0x53,0x33,0x30,0x20,0x2d,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x31,0x20,0x3d,0x20,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x32,0x20,0x3d,0x20,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x33,0x20,0x3d,0x20,0x2d,0x53,0x30,0x31,0x20,0x2b,0x20,0x53,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x33,0x20,0x3d,0x20,0x2d,0x53,0x31,0x31,0x20,0x2b,0x20,0x53,0x31,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x33,0x20,0x3d,0x20,0x2d,0x53,0x32,0x31,0x20,0x2b,0x20,0x53,0x32,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x33,0x20,0x3d,0x20,0x2d,0x53,0x33,0x31,0x20,0x2b,0x20,0x53,0x33,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x61,0x6c,0x70,0x68,0x61,0x2a,0x61,0x6c,0x70,0x68,0x61,0x2c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x30,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x2c,0x20,0x20,0x20,0x64,0x73,0x74,0x59,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x59,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x25,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x30,0x2a,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x29,0x20,0x2a,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x64,0x73,0x74,0x59,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x64,0x73,0x74,0x59,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x25,0x20,0x34,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2a,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2a,0x31,0x36,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x6d,0x30,0x30,0x20,0x2d,0x20,0x6d,0x32,0x30,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x30,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x30,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x30,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x30,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x32,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x6d,0x31,0x30,0x20,0x2b,0x20,0x6d,0x33,0x30,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x33,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x6d,0x30,0x31,0x20,0x2d,0x20,0x6d,0x32,0x31,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x31,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x35,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x31,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x31,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x36,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x6d,0x31,0x31,0x20,0x2b,0x20,0x6d,0x33,0x31,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x37,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x6d,0x30,0x32,0x20,0x2d,0x20,0x6d,0x32,0x32,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x32,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x39,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x32,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x32,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x30,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x6d,0x31,0x32,0x20,0x2b,0x20,0x6d,0x33,0x32,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x31,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x6d,0x30,0x33,0x20,0x2d,0x20,0x6d,0x32,0x33,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2b,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x33,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x33,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x31,0x33,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x35,0x66,0x20,0x2a,0x20,0x6d,0x32,0x33,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x34,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x2d,0x6d,0x31,0x33,0x20,0x2b,0x20,0x6d,0x33,0x33,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x35,0x2a,0x62,0x61,0x74,0x63,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x77,0x69,0x6e,0x6f,0x54,0x72,0x61,0x6e,0x73,0x44,0x73,0x74,0x42,0x75,0x66,0x32,0x5f,0x33,0x5f,0x31,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x75,0x42,0x69,0x61,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0x20,0x2f,0x2f,0x77,0x55,0x6e,0x69,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x2f,0x2f,0x68,0x55,0x6e,0x69,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x70,0x6f,0x73,0x2e,0x78,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x79,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x61,0x6c,0x50,0x6f,0x73,0x20,0x20,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x20,0x20,0x3d,0x20,0x28,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x3d,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2a,0x20,0x75,0x6e,0x69,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x75,0x6e,0x69,0x74,0x57,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x58,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x59,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x34,0x20,0x2a,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x7a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x25,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x69,0x61,0x73,0x20,0x20,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x42,0x69,0x61,0x73,0x2b,0x6f,0x7a,0x2a,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2f,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x62,0x61,0x74,0x63,0x68,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x62,0x61,0x74,0x63,0x68,0x4f,0x66,0x66,0x73,0x65,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x72,0x65,0x61,0x6c,0x50,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x72,0x65,0x61,0x6c,0x50,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0x20,0x61,0x6c,0x70,0x68,0x61,0x32,0x2c,0x20,0x34,0x2c,0x20,0x55,0x50,0x5f,0x44,0x49,0x56,0x28,0x77,0x55,0x6e,0x69,0x74,0x2a,0x68,0x55,0x6e,0x69,0x74,0x2c,0x34,0x29,0x5d,0x20,0x78,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x70,0x6f,0x73,0x2e,0x79,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x25,0x20,0x34,0x2c,0x20,0x64,0x73,0x74,0x58,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x31,0x36,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x64,0x73,0x74,0x58,0x4f,0x72,0x69,0x67,0x69,0x6e,0x20,0x25,0x20,0x34,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x64,0x73,0x74,0x58,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x31,0x36,0x2a,0x73,0x72,0x63,0x57,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x30,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x30,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x30,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x30,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x31,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x31,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x35,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x31,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x36,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x31,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x32,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x32,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x39,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x32,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x31,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x32,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x31,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x30,0x33,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x31,0x33,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x31,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x32,0x33,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x31,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x53,0x33,0x33,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x75,0x49,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x69,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x31,0x35,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x30,0x20,0x20,0x3d,0x20,0x2b,0x53,0x30,0x30,0x20,0x2b,0x20,0x53,0x30,0x31,0x20,0x2b,0x20,0x53,0x30,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x30,0x20,0x20,0x3d,0x20,0x2b,0x53,0x31,0x30,0x20,0x2b,0x20,0x53,0x31,0x31,0x20,0x2b,0x20,0x53,0x31,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x30,0x20,0x20,0x3d,0x20,0x2b,0x53,0x32,0x30,0x20,0x2b,0x20,0x53,0x32,0x31,0x20,0x2b,0x20,0x53,0x32,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x30,0x20,0x20,0x3d,0x20,0x2b,0x53,0x33,0x30,0x20,0x2b,0x20,0x53,0x33,0x31,0x20,0x2b,0x20,0x53,0x33,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x31,0x20,0x20,0x3d,0x20,0x2b,0x53,0x30,0x31,0x20,0x2d,0x20,0x53,0x30,0x32,0x20,0x2b,0x20,0x53,0x30,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x31,0x20,0x20,0x3d,0x20,0x2b,0x53,0x31,0x31,0x20,0x2d,0x20,0x53,0x31,0x32,0x20,0x2b,0x20,0x53,0x31,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x31,0x20,0x20,0x3d,0x20,0x2b,0x53,0x32,0x31,0x20,0x2d,0x20,0x53,0x32,0x32,0x20,0x2b,0x20,0x53,0x32,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x31,0x20,0x20,0x3d,0x20,0x2b,0x53,0x33,0x31,0x20,0x2d,0x20,0x53,0x33,0x32,0x20,0x2b,0x20,0x53,0x33,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x62,0x61,0x74,0x63,0x68,0x2c,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x62,0x61,0x74,0x63,0x68,0x49,0x6e,0x64,0x65,0x78,0x2c,0x20,0x6f,0x7a,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x79,0x53,0x74,0x61,0x72,0x74,0x2c,0x20,0x20,0x20,0x6f,0x78,0x53,0x74,0x61,0x72,0x74,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x49,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2b,0x20,0x6f,0x7a,0x29,0x20,0x2a,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x6f,0x79,0x53,0x74,0x61,0x72,0x74,0x29,0x20,0x2a,0x20,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x6f,0x78,0x53,0x74,0x61,0x72,0x74,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x78,0x20,0x3d,0x20,0x6f,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x79,0x20,0x3d,0x20,0x6f,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6f,0x78,0x20,0x3c,0x20,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x26,0x26,0x20,0x6f,0x79,0x20,0x3c,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x20,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x20,0x2b,0x20,0x6d,0x30,0x30,0x20,0x2b,0x20,0x6d,0x31,0x30,0x20,0x2b,0x20,0x6d,0x32,0x30,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x78,0x20,0x3d,0x20,0x6f,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x79,0x20,0x3d,0x20,0x6f,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6f,0x78,0x20,0x3c,0x20,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x26,0x26,0x20,0x6f,0x79,0x20,0x3c,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x20,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x20,0x2b,0x20,0x6d,0x31,0x30,0x20,0x2d,0x20,0x6d,0x32,0x30,0x20,0x2b,0x20,0x6d,0x33,0x30,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x78,0x20,0x3d,0x20,0x6f,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x79,0x20,0x3d,0x20,0x6f,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6f,0x78,0x20,0x3c,0x20,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x26,0x26,0x20,0x6f,0x79,0x20,0x3c,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x20,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x20,0x2b,0x20,0x6d,0x30,0x31,0x20,0x2b,0x20,0x6d,0x31,0x31,0x20,0x2b,0x20,0x6d,0x32,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x78,0x20,0x3d,0x20,0x6f,0x78,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x79,0x20,0x3d,0x20,0x6f,0x79,0x53,0x74,0x61,0x72,0x74,0x20,0x2b,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6f,0x78,0x20,0x3c,0x20,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x20,0x26,0x26,0x20,0x6f,0x79,0x20,0x3c,0x20,0x64,0x73,0x74,0x48,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x20,0x20,0x3d,0x20,0x62,0x69,0x61,0x73,0x20,0x2b,0x20,0x6d,0x31,0x31,0x20,0x2d,0x20,0x6d,0x32,0x31,0x20,0x2b,0x20,0x6d,0x33,0x31,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x52,0x45,0x4c,0x55,0x36,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x72,0x65,0x73,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x30,0x29,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x36,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x64,0x73,0x74,0x57,0x69,0x64,0x74,0x68,0x2b,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, +const char* winogradTransform_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_DIM2 "" __private int global_size_dim0,__private int global_size_dim1,\n" +"#define UNIFORM_BOUNDRY_CHECK(index0, index1) "" if(index0 >= global_size_dim0 || index1 >= global_size_dim1) { "" return; "" }\n" +"// [dstChannel,srcChannel,3,3] -> [4x4,srcChannelPad,dstChannelpad] (N,Kpad,Npad)\n" +"__kernel void winoTransWeightBuf2_3_1(GLOBAL_SIZE_DIM2\n" +" __global const float* input,// 0\n" +" __global FLOAT* output,\n" +" __private const int srcChannel,// 3\n" +" __private const int dstChannel,\n" +" __private const int srcChannelPad,// 6\n" +" __private const int dstChannelPad\n" +") {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" \n" +" const int src_c=pos.x;\n" +" const int dst_c=pos.y;\n" +" \n" +" const int out_offset=(0*srcChannelPad+src_c)*dstChannelPad+dst_c;\n" +" const int out_offset_add=srcChannelPad*dstChannelPad;\n" +" if(src_c >= srcChannel || dst_c >= dstChannel) {\n" +" for(int i=0; i<16; i++) {\n" +" output[out_offset+i*out_offset_add]=(FLOAT)0;\n" +" }\n" +" return;\n" +" }\n" +" \n" +" const int in_offset=(dst_c*srcChannel+src_c)*9;\n" +" FLOAT8 in=CONVERT_FLOAT8(vload8(0,input+in_offset));\n" +" FLOAT in8=input[in_offset+8];\n" +" \n" +" FLOAT GB_00=in.s0;\n" +" FLOAT GB_01=in.s1;\n" +" FLOAT GB_02=in.s2;\n" +" FLOAT GB_10=in.s0+in.s3+in.s6;\n" +" FLOAT GB_11=in.s1+in.s4+in.s7;\n" +" FLOAT GB_12=in.s2+in.s5+in8;\n" +" FLOAT GB_20=in.s0-in.s3+in.s6;\n" +" FLOAT GB_21=in.s1-in.s4+in.s7;\n" +" FLOAT GB_22=in.s2-in.s5+in8;\n" +" FLOAT GB_30=in.s6;\n" +" FLOAT GB_31=in.s7;\n" +" FLOAT GB_32=in8;\n" +" \n" +" FLOAT GBGT_00=GB_00;\n" +" FLOAT GBGT_01=GB_00+GB_01+GB_02;\n" +" FLOAT GBGT_02=GB_00-GB_01+GB_02;\n" +" FLOAT GBGT_03=GB_02;\n" +" \n" +" FLOAT GBGT_10=GB_10;\n" +" FLOAT GBGT_11=GB_10+GB_11+GB_12;\n" +" FLOAT GBGT_12=GB_10-GB_11+GB_12;\n" +" FLOAT GBGT_13=GB_12;\n" +" \n" +" FLOAT GBGT_20=GB_20;\n" +" FLOAT GBGT_21=GB_20+GB_21+GB_22;\n" +" FLOAT GBGT_22=GB_20-GB_21+GB_22;\n" +" FLOAT GBGT_23=GB_22;\n" +" \n" +" FLOAT GBGT_30=GB_30;\n" +" FLOAT GBGT_31=GB_30+GB_31+GB_32;\n" +" FLOAT GBGT_32=GB_30-GB_31+GB_32;\n" +" FLOAT GBGT_33=GB_32;\n" +" output[out_offset+0*out_offset_add]=GBGT_00;\n" +" output[out_offset+1*out_offset_add]=GBGT_01;\n" +" output[out_offset+2*out_offset_add]=GBGT_02;\n" +" output[out_offset+3*out_offset_add]=GBGT_03;\n" +" output[out_offset+4*out_offset_add]=GBGT_10;\n" +" output[out_offset+5*out_offset_add]=GBGT_11;\n" +" output[out_offset+6*out_offset_add]=GBGT_12;\n" +" output[out_offset+7*out_offset_add]=GBGT_13;\n" +" output[out_offset+8*out_offset_add]=GBGT_20;\n" +" output[out_offset+9*out_offset_add]=GBGT_21;\n" +" output[out_offset+10*out_offset_add]=GBGT_22;\n" +" output[out_offset+11*out_offset_add]=GBGT_23;\n" +" output[out_offset+12*out_offset_add]=GBGT_30;\n" +" output[out_offset+13*out_offset_add]=GBGT_31;\n" +" output[out_offset+14*out_offset_add]=GBGT_32;\n" +" output[out_offset+15*out_offset_add]=GBGT_33;\n" +"}\n" +"__kernel void winoTransSrcBuf2_3_1(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* uInput,// 0\n" +" __global FLOAT* uOutput,__private const int unitWidth,\n" +" __private const int unitHeight,// 3\n" +" __private const int padX,__private const int padY,\n" +" __private const int srcWidth,// 6\n" +" __private const int srcHeight,__private const int srcChannelC4,\n" +" __private const int dstHeightPad,__private const int srcChannelPad,\n" +" __private const int batchOffset) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1)); \n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" \n" +" if(pos.x >= unitWidth*unitHeight || pos.y >= srcChannelC4) {\n" +" return;\n" +" }\n" +" int unitWidth_idx=pos.x % unitWidth;\n" +" int unitHeight_idx=pos.x/unitWidth;\n" +" int2 realPos=(int2)(unitWidth_idx,unitHeight_idx);\n" +" int dstXOrigin=pos.y;\n" +" int batchIndex=pos.y/srcChannelC4;\n" +" int srcZ=pos.y % srcChannelC4;\n" +" int dstYOrigin=unitWidth*unitHeight_idx+unitWidth_idx;\n" +" int dstHeight=(unitWidth*unitHeight+3)/4;\n" +" int dstY=dstYOrigin/4;\n" +" int dstX=dstYOrigin % 4+4*dstXOrigin;\n" +" batchIndex=batchOffset;\n" +" {\n" +" int sxStart=(realPos.x)*2-padX;\n" +" int syStart=(realPos.y)*2-padY;\n" +" FLOAT4 S00;\n" +" FLOAT4 S10;\n" +" FLOAT4 S20;\n" +" FLOAT4 S30;\n" +" FLOAT4 S01;\n" +" FLOAT4 S11;\n" +" FLOAT4 S21;\n" +" FLOAT4 S31;\n" +" FLOAT4 S02;\n" +" FLOAT4 S12;\n" +" FLOAT4 S22;\n" +" FLOAT4 S32;\n" +" FLOAT4 S03;\n" +" FLOAT4 S13;\n" +" FLOAT4 S23;\n" +" FLOAT4 S33;\n" +" \n" +" int inp_offset=(((batchIndex*srcChannelC4+srcZ)*srcHeight+syStart)*srcWidth+sxStart)*4;\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=0+syStart;\n" +" \n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S00=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=0+syStart;\n" +" \n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S10=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=0+syStart;\n" +" \n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S20=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=0+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S30=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12);\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S01=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S11=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S21=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S31=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth+12);\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S02=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S12=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S22=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S32=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth+12);\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S03=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S13=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S23=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S33=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth+12);\n" +" }\n" +" FLOAT4 m00=+S00-S02;\n" +" FLOAT4 m10=+S10-S12;\n" +" FLOAT4 m20=+S20-S22;\n" +" FLOAT4 m30=+S30-S32;\n" +" FLOAT4 m01=+(FLOAT)0.5f*S01+(FLOAT)0.5f*S02;\n" +" FLOAT4 m11=+(FLOAT)0.5f*S11+(FLOAT)0.5f*S12;\n" +" FLOAT4 m21=+(FLOAT)0.5f*S21+(FLOAT)0.5f*S22;\n" +" FLOAT4 m31=+(FLOAT)0.5f*S31+(FLOAT)0.5f*S32;\n" +" FLOAT4 m02=-(FLOAT)0.5f*S01+(FLOAT)0.5f*S02;\n" +" FLOAT4 m12=-(FLOAT)0.5f*S11+(FLOAT)0.5f*S12;\n" +" FLOAT4 m22=-(FLOAT)0.5f*S21+(FLOAT)0.5f*S22;\n" +" FLOAT4 m32=-(FLOAT)0.5f*S31+(FLOAT)0.5f*S32;\n" +" FLOAT4 m03=-S01+S03;\n" +" FLOAT4 m13=-S11+S13;\n" +" FLOAT4 m23=-S21+S23;\n" +" FLOAT4 m33=-S31+S33;\n" +" \n" +" //NC4HW4 [alpha*alpha,srcChannelPad,dstHeightPad]\n" +" //index: [0,dstXOrigin,dstY,dstYOrigin % 4]\n" +" int out_offset=(0*srcChannelPad+4*dstXOrigin)*dstHeightPad+dstYOrigin;\n" +" int batch_offset=srcChannelPad*dstHeightPad;\n" +" \n" +" FLOAT4 res=(+m00-m20);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" out_offset += batch_offset;\n" +" res=(+(FLOAT)0.5f*m10+(FLOAT)0.5f*m20);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-(FLOAT)0.5f*m10+(FLOAT)0.5f*m20);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-m10+m30);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" \n" +" out_offset += batch_offset;\n" +" res=(+m01-m21);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(+(FLOAT)0.5f*m11+(FLOAT)0.5f*m21);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-(FLOAT)0.5f*m11+(FLOAT)0.5f*m21);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-m11+m31);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(+m02-m22);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(+(FLOAT)0.5f*m12+(FLOAT)0.5f*m22);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-(FLOAT)0.5f*m12+(FLOAT)0.5f*m22);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-m12+m32);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(+m03-m23);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(+(FLOAT)0.5f*m13+(FLOAT)0.5f*m23);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-(FLOAT)0.5f*m13+(FLOAT)0.5f*m23);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" \n" +" out_offset += batch_offset;\n" +" res=(-m13+m33);\n" +" uOutput[out_offset]=res.x;\n" +" uOutput[out_offset+dstHeightPad]=res.y;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad]=res.z;\n" +" uOutput[out_offset+dstHeightPad+dstHeightPad+dstHeightPad]=res.w;\n" +" }\n" +"}\n" +"__kernel void winoTransDstBuf2_3_1(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* uInput,\n" +" __global const FLOAT* uBias,\n" +" __global FLOAT* uOutput,\n" +" __private const int unitWidth,//wUnit\n" +" __private const int unitHeight,//hUnit\n" +" __private const int dstWidth,\n" +" __private const int dstHeight,\n" +" __private const int dstChannelC4,\n" +" __private const int srcWidthPad,\n" +" __private const int dstChannelPad,\n" +" __private const int batchOffset) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" int unitWidth_idx=pos.x % unitWidth;\n" +" int unitHeight_idx=pos.x/unitWidth;\n" +" int2 realPos=(int2)(unitWidth_idx,unitHeight_idx);\n" +" int srcWidth=(unitWidth*unitHeight+3)/4;\n" +" int dstXOrigin=unitWidth*unitHeight_idx+unitWidth_idx;\n" +" int dstX=dstXOrigin/4;\n" +" int dstY=4*pos.y+dstXOrigin % 4;\n" +" int oz=pos.y % dstChannelC4;\n" +" \n" +" FLOAT4 bias=vload4(0,uBias+oz*4);\n" +" int batchIndex=pos.y/dstChannelC4;\n" +" batchIndex=batchOffset;\n" +" {\n" +" int oyStart=realPos.y*2;\n" +" int oxStart=realPos.x*2;\n" +" \n" +" // [alpha2,srcWidthPad,dstChannelPad]\n" +" //index: [0,dstXOrigin,4*oz]\n" +" const int inp_offset=(0*srcWidthPad+dstXOrigin)*dstChannelPad+4*oz;\n" +" const int b_offset=dstChannelPad*srcWidthPad;\n" +" FLOAT4 S00=vload4(0,uInput+inp_offset+b_offset*0);\n" +" FLOAT4 S10=vload4(0,uInput+inp_offset+b_offset*1);\n" +" FLOAT4 S20=vload4(0,uInput+inp_offset+b_offset*2);\n" +" FLOAT4 S30=vload4(0,uInput+inp_offset+b_offset*3);\n" +" FLOAT4 S01=vload4(0,uInput+inp_offset+b_offset*4);\n" +" FLOAT4 S11=vload4(0,uInput+inp_offset+b_offset*5);\n" +" FLOAT4 S21=vload4(0,uInput+inp_offset+b_offset*6);\n" +" FLOAT4 S31=vload4(0,uInput+inp_offset+b_offset*7);\n" +" FLOAT4 S02=vload4(0,uInput+inp_offset+b_offset*8);\n" +" FLOAT4 S12=vload4(0,uInput+inp_offset+b_offset*9);\n" +" FLOAT4 S22=vload4(0,uInput+inp_offset+b_offset*10);\n" +" FLOAT4 S32=vload4(0,uInput+inp_offset+b_offset*11);\n" +" FLOAT4 S03=vload4(0,uInput+inp_offset+b_offset*12);\n" +" FLOAT4 S13=vload4(0,uInput+inp_offset+b_offset*13);\n" +" FLOAT4 S23=vload4(0,uInput+inp_offset+b_offset*14);\n" +" FLOAT4 S33=vload4(0,uInput+inp_offset+b_offset*15);\n" +" FLOAT4 m00=+S00+S01+S02;\n" +" FLOAT4 m10=+S10+S11+S12;\n" +" FLOAT4 m20=+S20+S21+S22;\n" +" FLOAT4 m30=+S30+S31+S32;\n" +" FLOAT4 m01=+S01-S02+S03;\n" +" FLOAT4 m11=+S11-S12+S13;\n" +" FLOAT4 m21=+S21-S22+S23;\n" +" FLOAT4 m31=+S31-S32+S33;\n" +" \n" +" //NC4HW4 [batch,dstChannelC4,dstHeight,dstWidth]\n" +" //index: [batchIndex,oz,oyStart,oxStart]\n" +" int out_offset=(((batchIndex*dstChannelC4+ oz)*dstHeight+oyStart)*dstWidth+oxStart)*4;\n" +" {\n" +" int ox=oxStart+0;\n" +" int oy=oyStart+0;\n" +" if (ox= global_size_dim0 || index1 >= global_size_dim1) { "" return; "" }\n" +" \n" +"#pragma OPENCL EXTENSION cl_intel_subgroups : enable\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void winoTransSrcBuf2_3_1_c16_c16(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* uInput,// 0\n" +" __global FLOAT* uOutput,__private const int unitWidth,\n" +" __private const int unitHeight,// 3\n" +" __private const int padX,__private const int padY,\n" +" __private const int srcWidth,// 6\n" +" __private const int srcHeight,__private const int srcChannelC4,__private const int srcChannelC16,__private const int dstHeight,\n" +" __private const int batchOffset,\n" +" __private const int input_pad_left,__private const int input_pad_right) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1)); \n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" const int unitWidth_idx=pos.x % unitWidth;\n" +" const int unitHeight_idx=pos.x/unitWidth;\n" +" const int sglid=get_sub_group_local_id();\n" +" const int pos_y=get_group_id(1);\n" +" int2 realPos=(int2)(unitWidth_idx,unitHeight_idx);\n" +" int src_pitch=srcWidth+input_pad_left+input_pad_right;\n" +" \n" +" {\n" +" int sxStart=(realPos.x)*2-padX;\n" +" int syStart=(realPos.y)*2-padY;\n" +" FLOAT4 S[4];\n" +" \n" +" int inp_offset=(((batchOffset*srcChannelC16+pos_y)*srcHeight+syStart)*src_pitch+sxStart+input_pad_left)*16;\n" +" for(int i=0; i<4; ++i){\n" +" int sy=i+syStart;\n" +" if(sy<0 || sy >= srcHeight){\n" +" S[i]=(FLOAT4)0;\n" +" }else{\n" +"#ifdef MNN_SUPPORT_FP16\n" +" S[i]=as_half4(intel_sub_group_block_read_us4((__global ushort*)(uInput+inp_offset)));\n" +"#else\n" +" S[i]=as_float4(intel_sub_group_block_read4((__global uint*)(uInput+inp_offset)));\n" +"#endif\n" +" }\n" +" inp_offset += 16*src_pitch;\n" +" }\n" +" FLOAT m00=+S[0].s0-S[2].s0;\n" +" FLOAT m10=+S[0].s1-S[2].s1;\n" +" FLOAT m20=+S[0].s2-S[2].s2;\n" +" FLOAT m30=+S[0].s3-S[2].s3;\n" +" FLOAT m01=+(FLOAT)0.5f*S[1].s0+(FLOAT)0.5f*S[2].s0;\n" +" FLOAT m11=+(FLOAT)0.5f*S[1].s1+(FLOAT)0.5f*S[2].s1;\n" +" FLOAT m21=+(FLOAT)0.5f*S[1].s2+(FLOAT)0.5f*S[2].s2;\n" +" FLOAT m31=+(FLOAT)0.5f*S[1].s3+(FLOAT)0.5f*S[2].s3;\n" +" FLOAT m02=-(FLOAT)0.5f*S[1].s0+(FLOAT)0.5f*S[2].s0;\n" +" FLOAT m12=-(FLOAT)0.5f*S[1].s1+(FLOAT)0.5f*S[2].s1;\n" +" FLOAT m22=-(FLOAT)0.5f*S[1].s2+(FLOAT)0.5f*S[2].s2;\n" +" FLOAT m32=-(FLOAT)0.5f*S[1].s3+(FLOAT)0.5f*S[2].s3;\n" +" FLOAT m03=-S[1].s0+S[3].s0;\n" +" FLOAT m13=-S[1].s1+S[3].s1;\n" +" FLOAT m23=-S[1].s2+S[3].s2;\n" +" FLOAT m33=-S[1].s3+S[3].s3;\n" +" \n" +" //NC4HW4 [alpha*alpha,srcChannelC16,dstHeight,16]\n" +" //index: [0,pos.y/16,pos.x,0]\n" +" int out_offset=(pos_y*dstHeight+pos.x)*16+sglid;\n" +" int batch_offset=srcChannelC16*dstHeight*16;\n" +" uOutput[out_offset+0*batch_offset]=+m00-m20;\n" +" uOutput[out_offset+1*batch_offset]=+(FLOAT)0.5f*m10+(FLOAT)0.5f*m20;\n" +" uOutput[out_offset+2*batch_offset]=-(FLOAT)0.5f*m10+(FLOAT)0.5f*m20;\n" +" uOutput[out_offset+3*batch_offset]=-m10+m30;\n" +" uOutput[out_offset+4*batch_offset]=+m01-m21;\n" +" uOutput[out_offset+5*batch_offset]=+(FLOAT)0.5f*m11+(FLOAT)0.5f*m21;\n" +" uOutput[out_offset+6*batch_offset]=-(FLOAT)0.5f*m11+(FLOAT)0.5f*m21;\n" +" uOutput[out_offset+7*batch_offset]=-m11+m31;\n" +" uOutput[out_offset+8*batch_offset]=+m02-m22;\n" +" uOutput[out_offset+9*batch_offset]=+(FLOAT)0.5f*m12+(FLOAT)0.5f*m22;\n" +" uOutput[out_offset+10*batch_offset]=-(FLOAT)0.5f*m12+(FLOAT)0.5f*m22;\n" +" uOutput[out_offset+11*batch_offset]=-m12+m32;\n" +" uOutput[out_offset+12*batch_offset]=+m03-m23;\n" +" uOutput[out_offset+13*batch_offset]=+(FLOAT)0.5f*m13+(FLOAT)0.5f*m23;\n" +" uOutput[out_offset+14*batch_offset]=-(FLOAT)0.5f*m13+(FLOAT)0.5f*m23;\n" +" uOutput[out_offset+15*batch_offset]=-m13+m33;\n" +" }\n" +"}\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void winoTransDstBuf2_3_1_c16_c16(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* uInput,\n" +" __global const FLOAT* uBias,\n" +" __global FLOAT* uOutput,\n" +" __private const int unitWidth,//wUnit\n" +" __private const int unitHeight,//hUnit\n" +" __private const int dstWidth,\n" +" __private const int dstHeight,\n" +" __private const int dstChannelC4,__private const int dstChannelC16,__private const int srcWidth,\n" +" __private const int batchOffset,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" const int unitWidth_idx=pos.x % unitWidth;\n" +" const int unitHeight_idx=pos.x/unitWidth; \n" +" const int sglid=get_sub_group_local_id();\n" +" const int pos_y=get_group_id(1);\n" +" int2 realPos=(int2)(unitWidth_idx,unitHeight_idx);\n" +" \n" +" FLOAT bias=uBias[pos.y];\n" +" {\n" +" int oyStart=realPos.y*2;\n" +" int oxStart=realPos.x*2;\n" +" \n" +" //NC4HW4 [alpha2,dstChannelC16,wUnit*hUnit,16]\n" +" //index: [0,pos.y/4,pos.x,pos.y%4]\n" +" const int inp_offset=(pos_y*srcWidth+pos.x)*16+sglid;\n" +" const int ic_offset=16*srcWidth*dstChannelC16;\n" +" FLOAT S00=uInput[inp_offset+ic_offset*0];\n" +" FLOAT S10=uInput[inp_offset+ic_offset*1];\n" +" FLOAT S20=uInput[inp_offset+ic_offset*2];\n" +" FLOAT S30=uInput[inp_offset+ic_offset*3];\n" +" FLOAT S01=uInput[inp_offset+ic_offset*4];\n" +" FLOAT S11=uInput[inp_offset+ic_offset*5];\n" +" FLOAT S21=uInput[inp_offset+ic_offset*6];\n" +" FLOAT S31=uInput[inp_offset+ic_offset*7];\n" +" FLOAT S02=uInput[inp_offset+ic_offset*8];\n" +" FLOAT S12=uInput[inp_offset+ic_offset*9];\n" +" FLOAT S22=uInput[inp_offset+ic_offset*10];\n" +" FLOAT S32=uInput[inp_offset+ic_offset*11];\n" +" FLOAT S03=uInput[inp_offset+ic_offset*12];\n" +" FLOAT S13=uInput[inp_offset+ic_offset*13];\n" +" FLOAT S23=uInput[inp_offset+ic_offset*14];\n" +" FLOAT S33=uInput[inp_offset+ic_offset*15];\n" +" FLOAT m00=+S00+S01+S02;\n" +" FLOAT m10=+S10+S11+S12;\n" +" FLOAT m20=+S20+S21+S22;\n" +" FLOAT m30=+S30+S31+S32;\n" +" FLOAT m01=+S01-S02+S03;\n" +" FLOAT m11=+S11-S12+S13;\n" +" FLOAT m21=+S21-S22+S23;\n" +" FLOAT m31=+S31-S32+S33;\n" +" \n" +" //NC4HW4 [batch,dstChannelC4,dstHeight,dstWidth]\n" +" //index: [batchOffset,pos.y,oyStart,oxStart]\n" +" int dst_pitch=dstWidth+output_pad_left+output_pad_right;\n" +" int out_offset=(((batchOffset*dstChannelC16+ pos_y)*dstHeight+oyStart)*dst_pitch+oxStart+output_pad_left)*16+sglid;\n" +" {\n" +" FLOAT2 res=(FLOAT2)(bias+m00+m10+m20,bias+m10-m20+m30);\n" +"#ifdef RELU\n" +" res=max(res,(FLOAT2)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" res=clamp(res,(FLOAT2)0,(FLOAT2)6);\n" +"#endif\n" +"#if OUTPUT_LEFTOVERS\n" +" uOutput[out_offset]=res.x;\n" +" if(oxStart+1< dstWidth){\n" +" uOutput[out_offset+16]=res.y;\n" +" }\n" +"#else\n" +"#ifdef MNN_SUPPORT_FP16\n" +" intel_sub_group_block_write_us2((__global ushort*)(uOutput+out_offset),as_ushort2(res));\n" +"#else\n" +" intel_sub_group_block_write2((__global uint*)(uOutput+out_offset),as_uint2(res));\n" +"#endif\n" +"#endif //OUTPUT_LEFTOVERS\n" +" }\n" +" {\n" +" int oy=oyStart+1;\n" +" if (oy= srcWidth || sy<0 || sy >= srcHeight);\n" +" S00=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=0+syStart;\n" +" \n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S10=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=0+syStart;\n" +" \n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S20=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=0+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S30=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12);\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S01=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S11=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S21=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=1+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S31=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+4*srcWidth+12);\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S02=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S12=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S22=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=2+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S32=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+8*srcWidth+12);\n" +" }\n" +" {\n" +" int sx=0+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S03=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth);\n" +" }\n" +" {\n" +" int sx=1+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S13=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth+4);\n" +" }\n" +" {\n" +" int sx=2+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S23=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth+8);\n" +" }\n" +" {\n" +" int sx=3+sxStart;\n" +" int sy=3+syStart;\n" +" bool outBound=(sx<0 || sx >= srcWidth || sy<0 || sy >= srcHeight);\n" +" S33=outBound ? (FLOAT4)(0) : vload4(0,uInput+inp_offset+12*srcWidth+12);\n" +" }\n" +" FLOAT4 m00=+S00-S02;\n" +" FLOAT4 m10=+S10-S12;\n" +" FLOAT4 m20=+S20-S22;\n" +" FLOAT4 m30=+S30-S32;\n" +" FLOAT4 m01=+(FLOAT)0.5f*S01+(FLOAT)0.5f*S02;\n" +" FLOAT4 m11=+(FLOAT)0.5f*S11+(FLOAT)0.5f*S12;\n" +" FLOAT4 m21=+(FLOAT)0.5f*S21+(FLOAT)0.5f*S22;\n" +" FLOAT4 m31=+(FLOAT)0.5f*S31+(FLOAT)0.5f*S32;\n" +" FLOAT4 m02=-(FLOAT)0.5f*S01+(FLOAT)0.5f*S02;\n" +" FLOAT4 m12=-(FLOAT)0.5f*S11+(FLOAT)0.5f*S12;\n" +" FLOAT4 m22=-(FLOAT)0.5f*S21+(FLOAT)0.5f*S22;\n" +" FLOAT4 m32=-(FLOAT)0.5f*S31+(FLOAT)0.5f*S32;\n" +" FLOAT4 m03=-S01+S03;\n" +" FLOAT4 m13=-S11+S13;\n" +" FLOAT4 m23=-S21+S23;\n" +" FLOAT4 m33=-S31+S33;\n" +" \n" +" //NC4HW4 [alpha*alpha,srcChannelC16,dstHeight,16]\n" +" //index: [0,pos.y/4,pos.x,pos.y % 4]\n" +" int out_offset=((pos.y/4)*dstHeight+pos.x)*16+(pos.y % 4)*4;\n" +" int batch_offset=srcChannelC16*dstHeight*16;\n" +" vstore4(+m00-m20,0,uOutput+out_offset+0*batch_offset);\n" +" vstore4(+(FLOAT)0.5f*m10+(FLOAT)0.5f*m20,0,uOutput+out_offset+1*batch_offset);\n" +" vstore4(-(FLOAT)0.5f*m10+(FLOAT)0.5f*m20,0,uOutput+out_offset+2*batch_offset);\n" +" vstore4(-m10+m30,0,uOutput+out_offset+3*batch_offset);\n" +" vstore4(+m01-m21,0,uOutput+out_offset+4*batch_offset);\n" +" vstore4(+(FLOAT)0.5f*m11+(FLOAT)0.5f*m21,0,uOutput+out_offset+5*batch_offset);\n" +" vstore4(-(FLOAT)0.5f*m11+(FLOAT)0.5f*m21,0,uOutput+out_offset+6*batch_offset);\n" +" vstore4(-m11+m31,0,uOutput+out_offset+7*batch_offset);\n" +" vstore4(+m02-m22,0,uOutput+out_offset+8*batch_offset);\n" +" vstore4(+(FLOAT)0.5f*m12+(FLOAT)0.5f*m22,0,uOutput+out_offset+9*batch_offset);\n" +" vstore4(-(FLOAT)0.5f*m12+(FLOAT)0.5f*m22,0,uOutput+out_offset+10*batch_offset);\n" +" vstore4(-m12+m32,0,uOutput+out_offset+11*batch_offset);\n" +" vstore4(+m03-m23,0,uOutput+out_offset+12*batch_offset);\n" +" vstore4(+(FLOAT)0.5f*m13+(FLOAT)0.5f*m23,0,uOutput+out_offset+13*batch_offset);\n" +" vstore4(-(FLOAT)0.5f*m13+(FLOAT)0.5f*m23,0,uOutput+out_offset+14*batch_offset);\n" +" vstore4(-m13+m33,0,uOutput+out_offset+15*batch_offset);\n" +" }\n" +"}\n" +"__kernel void winoTransDstBuf2_3_1_c16_c4(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* uInput,\n" +" __global const FLOAT* uBias,\n" +" __global FLOAT* uOutput,\n" +" __private const int unitWidth,//wUnit\n" +" __private const int unitHeight,//hUnit\n" +" __private const int dstWidth,\n" +" __private const int dstHeight,\n" +" __private const int dstChannelC4,__private const int dstChannelC16,__private const int srcWidth,\n" +" __private const int batchOffset,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" int unitWidth_idx=pos.x % unitWidth;\n" +" int unitHeight_idx=pos.x/unitWidth;\n" +" int2 realPos=(int2)(unitWidth_idx,unitHeight_idx);\n" +" \n" +" FLOAT4 bias=vload4(0,uBias+pos.y*4);\n" +" {\n" +" int oyStart=realPos.y*2;\n" +" int oxStart=realPos.x*2;\n" +" \n" +" //NC4HW4 [alpha2,dstChannelC16,wUnit*hUnit,16]\n" +" //index: [0,pos.y/4,pos.x,pos.y%4]\n" +" const int inp_offset=((pos.y/4)*srcWidth+pos.x)*16+(pos.y % 4)*4;\n" +" const int ic_offset=16*srcWidth*dstChannelC16;\n" +" FLOAT4 S00=vload4(0,uInput+inp_offset+ic_offset*0);\n" +" FLOAT4 S10=vload4(0,uInput+inp_offset+ic_offset*1);\n" +" FLOAT4 S20=vload4(0,uInput+inp_offset+ic_offset*2);\n" +" FLOAT4 S30=vload4(0,uInput+inp_offset+ic_offset*3);\n" +" FLOAT4 S01=vload4(0,uInput+inp_offset+ic_offset*4);\n" +" FLOAT4 S11=vload4(0,uInput+inp_offset+ic_offset*5);\n" +" FLOAT4 S21=vload4(0,uInput+inp_offset+ic_offset*6);\n" +" FLOAT4 S31=vload4(0,uInput+inp_offset+ic_offset*7);\n" +" FLOAT4 S02=vload4(0,uInput+inp_offset+ic_offset*8);\n" +" FLOAT4 S12=vload4(0,uInput+inp_offset+ic_offset*9);\n" +" FLOAT4 S22=vload4(0,uInput+inp_offset+ic_offset*10);\n" +" FLOAT4 S32=vload4(0,uInput+inp_offset+ic_offset*11);\n" +" FLOAT4 S03=vload4(0,uInput+inp_offset+ic_offset*12);\n" +" FLOAT4 S13=vload4(0,uInput+inp_offset+ic_offset*13);\n" +" FLOAT4 S23=vload4(0,uInput+inp_offset+ic_offset*14);\n" +" FLOAT4 S33=vload4(0,uInput+inp_offset+ic_offset*15);\n" +" FLOAT4 m00=+S00+S01+S02;\n" +" FLOAT4 m10=+S10+S11+S12;\n" +" FLOAT4 m20=+S20+S21+S22;\n" +" FLOAT4 m30=+S30+S31+S32;\n" +" FLOAT4 m01=+S01-S02+S03;\n" +" FLOAT4 m11=+S11-S12+S13;\n" +" FLOAT4 m21=+S21-S22+S23;\n" +" FLOAT4 m31=+S31-S32+S33;\n" +" \n" +" //NC4HW4 [batch,dstChannelC4,dstHeight,dstWidth]\n" +" //index: [batchOffset,pos.y,oyStart,oxStart]\n" +" int out_offset=(((batchOffset*dstChannelC4+ pos.y)*dstHeight+oyStart)*dstWidth+oxStart)*4;\n" +" {\n" +" int ox=oxStart+0;\n" +" int oy=oyStart+0;\n" +" if (ox> 2;\n" +" const int area_4=(shape.z+3) >> 2;\n" +" const int in_offset=((b*channel_4+c_4)*area_4*2+hw_4)*16;\n" +" const int out_offset=((b*channel_4+c_4)*area_4+hw_4)*16;\n" +" float16 valueL=convert_float16(vload16(0,input+in_offset));\n" +" float16 valueR=convert_float16(vload16(area_4,input+in_offset));\n" +" #ifdef DOUBLE_INPUTS\n" +" float4 valueConstL=convert_float4(vload4(hw,input1));\n" +" float4 valueConstR=convert_float4(vload4(area_4+hw,input1));\n" +" valueL += (float16)((float4)valueConstL.x,(float4)valueConstL.y,(float4)valueConstL.z,(float4)valueConstL.w);\n" +" valueR += (float16)((float4)valueConstR.x,(float4)valueConstR.y,(float4)valueConstR.z,(float4)valueConstR.w);\n" +" #endif\n" +" float16 out=(erf(valueR*(float16)0.7071067932881648)+(float16)1.0)*valueR*(float16)0.5;\n" +" out *= valueL;\n" +" vstore16(CONVERT_FLOAT16(out),0,output+out_offset);\n" +"#else\n" +" const int hw=pos.z;\n" +" \n" +" const int channel_4=(shape.y+3) >> 2;\n" +" const int in_offset=((b*channel_4+c_4)*shape.z*2+hw)*4;\n" +" const int out_offset=((b*channel_4+c_4)*shape.z+hw)*4;\n" +" \n" +" float4 valueL=convert_float4(vload4(0,input+in_offset));\n" +" float4 valueR=convert_float4(vload4(shape.z,input+in_offset));\n" +" #ifdef DOUBLE_INPUTS\n" +" float valueConstL=input1[hw];\n" +" float valueConstR=input1[shape.z+hw];\n" +" valueL += (float4)valueConstL;\n" +" valueR += (float4)valueConstR;\n" +" #endif\n" +" float4 out=(erf(valueR*(float4)0.7071067932881648)+(float4)1.0)*valueR*(float4)0.5;\n" +" out *= valueL;\n" +" vstore4(CONVERT_FLOAT4(out),0,output+out_offset);\n" +"#endif\n" +" }\n" +"}\n" +; #endif -{ - "grid_sample", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x7b,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x5a,0x45,0x52,0x4f,0x53,0x20,0x3d,0x20,0x30,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x3d,0x20,0x31,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x52,0x45,0x46,0x4c,0x45,0x43,0x54,0x49,0x4f,0x4e,0x20,0x3d,0x20,0x32,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x4d,0x49,0x4e,0x20,0x3d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x5a,0x45,0x52,0x4f,0x53,0x2c,0xa,0x20,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x4d,0x41,0x58,0x20,0x3d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x52,0x45,0x46,0x4c,0x45,0x43,0x54,0x49,0x4f,0x4e,0xa,0x7d,0x3b,0xa,0xa,0x66,0x6c,0x6f,0x61,0x74,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x2c,0x20,0x69,0x6e,0x74,0x20,0x72,0x61,0x6e,0x67,0x65,0x2c,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x61,0x20,0x3d,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x20,0x3d,0x3d,0x20,0x31,0x3f,0x20,0x31,0x2e,0x30,0x66,0x20,0x3a,0x20,0x30,0x2e,0x30,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x62,0x20,0x3d,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x20,0x3d,0x3d,0x20,0x31,0x3f,0x20,0x30,0x2e,0x30,0x66,0x20,0x3a,0x20,0x31,0x2e,0x30,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x28,0x31,0x20,0x2b,0x20,0x78,0x29,0x20,0x2a,0x20,0x28,0x72,0x61,0x6e,0x67,0x65,0x20,0x2d,0x20,0x61,0x29,0x20,0x2d,0x20,0x62,0x29,0x20,0x2f,0x20,0x32,0x2e,0x30,0x66,0x3b,0xa,0x7d,0xa,0xa,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x69,0x6e,0x74,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x69,0x6e,0x74,0x20,0x76,0x2c,0x20,0x69,0x6e,0x74,0x20,0x6d,0x69,0x6e,0x2c,0x20,0x69,0x6e,0x74,0x20,0x6d,0x61,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x76,0x29,0x20,0x3c,0x20,0x6d,0x69,0x6e,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x76,0x29,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x28,0x76,0x29,0x20,0x3e,0x20,0x6d,0x61,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x76,0x29,0x20,0x3d,0x20,0x6d,0x61,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x3b,0xa,0x7d,0xa,0xa,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x74,0x20,0x68,0x2c,0x20,0x69,0x6e,0x74,0x20,0x77,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x74,0x6d,0x70,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x68,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x68,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x7c,0x7c,0x20,0x77,0x20,0x3c,0x20,0x30,0x20,0x7c,0x7c,0x20,0x77,0x20,0x3e,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x20,0x3d,0x3d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x5f,0x5a,0x45,0x52,0x4f,0x53,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,0x2e,0x30,0x66,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x43,0x6c,0x65,0x61,0x72,0x6c,0x79,0x2c,0x20,0x43,0x4c,0x41,0x4d,0x50,0x20,0x69,0x73,0x20,0x74,0x68,0x65,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x77,0x61,0x79,0x20,0x74,0x6f,0x20,0x67,0x6f,0x20,0x66,0x6f,0x72,0x20,0x47,0x72,0x69,0x64,0x53,0x61,0x6d,0x70,0x6c,0x65,0x50,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x5f,0x42,0x4f,0x52,0x44,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x46,0x6f,0x72,0x20,0x47,0x72,0x69,0x64,0x53,0x61,0x6d,0x70,0x6c,0x65,0x50,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x5f,0x52,0x45,0x46,0x4c,0x45,0x43,0x54,0x49,0x4f,0x4e,0x2c,0x20,0x73,0x69,0x6e,0x63,0x65,0x20,0x77,0x65,0x20,0x68,0x61,0x76,0x65,0x20,0x72,0x65,0x66,0x6c,0x65,0x63,0x74,0x65,0x64,0x20,0x74,0x68,0x65,0x20,0x76,0x61,0x6c,0x75,0x65,0x73,0x20,0x69,0x6e,0x74,0x6f,0x20,0x28,0x2d,0x31,0x2c,0x20,0x31,0x29,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x74,0x68,0x65,0x20,0x6c,0x65,0x66,0x74,0x6f,0x76,0x65,0x72,0x20,0x72,0x65,0x66,0x6c,0x65,0x63,0x74,0x69,0x6f,0x6e,0x73,0x20,0x64,0x65,0x67,0x72,0x61,0x64,0x65,0x20,0x74,0x6f,0x20,0x47,0x72,0x69,0x64,0x53,0x61,0x6d,0x70,0x6c,0x65,0x50,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x5f,0x42,0x4f,0x52,0x44,0x45,0x52,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x68,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x68,0x2c,0x20,0x30,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x20,0x3d,0x20,0x43,0x4c,0x41,0x4d,0x50,0x28,0x77,0x2c,0x20,0x30,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x52,0x49,0x5f,0x46,0x28,0x74,0x6d,0x70,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x77,0x2c,0x20,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x68,0x29,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6e,0x65,0x61,0x72,0x65,0x73,0x74,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x67,0x72,0x69,0x64,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x72,0x69,0x64,0x20,0x64,0x61,0x74,0x61,0x20,0x66,0x6f,0x72,0x6d,0x61,0x74,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x65,0x64,0x20,0x66,0x72,0x6f,0x6d,0x20,0x6e,0x63,0x68,0x77,0x20,0x74,0x6f,0x20,0x6e,0x63,0x34,0x68,0x77,0x34,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x6c,0x69,0x63,0x65,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x6c,0x69,0x63,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x31,0x2c,0x79,0x31,0x29,0x2e,0x2e,0x2e,0x28,0x78,0x6e,0x2c,0x79,0x31,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x29,0x20,0x28,0x79,0x31,0x2c,0x79,0x32,0x2c,0x79,0x33,0x2c,0x79,0x34,0x29,0x20,0x7c,0x20,0x28,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x2c,0x78,0x31,0x29,0x20,0x28,0x79,0x35,0x2c,0x79,0x36,0x2c,0x79,0x37,0x2c,0x79,0x38,0x29,0x20,0x7c,0x20,0x2e,0x2e,0x2e,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x7c,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x7c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x3c,0x2d,0x3e,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x7c,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x7c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x7c,0x20,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2e,0x20,0x7c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x31,0x2c,0x79,0x6d,0x29,0x2e,0x2e,0x2e,0x28,0x78,0x6e,0x2c,0x79,0x6d,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x29,0x20,0x28,0x79,0x31,0x2c,0x79,0x32,0x2c,0x79,0x33,0x2c,0x79,0x34,0x29,0x20,0x7c,0x20,0x28,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x2c,0x78,0x6e,0x29,0x20,0x28,0x79,0x35,0x2c,0x79,0x36,0x2c,0x79,0x37,0x2c,0x79,0x38,0x29,0x20,0x7c,0x20,0x2e,0x2e,0x2e,0xa,0x20,0x20,0x20,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x6c,0x69,0x63,0x65,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x72,0x69,0x64,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x72,0x69,0x64,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x67,0x72,0x69,0x64,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x72,0x69,0x64,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x73,0x6c,0x69,0x63,0x65,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x67,0x72,0x69,0x64,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x72,0x69,0x64,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x73,0x6c,0x69,0x63,0x65,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x61,0x72,0x72,0x5b,0x38,0x5d,0x20,0x3d,0x20,0x7b,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x77,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x77,0x7d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x65,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x79,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0x20,0x74,0x6f,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x63,0x6f,0x6f,0x72,0x64,0x69,0x6e,0x61,0x74,0x65,0x20,0x72,0x61,0x6e,0x67,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x65,0x74,0x20,0x6e,0x65,0x61,0x72,0x65,0x73,0x74,0x20,0x70,0x6f,0x69,0x6e,0x74,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6e,0x77,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x2b,0x20,0x30,0x2e,0x35,0x66,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6e,0x68,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x2b,0x20,0x30,0x2e,0x35,0x66,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x6e,0x68,0x2c,0x20,0x6e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6c,0x69,0x6e,0x65,0x61,0x72,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x67,0x72,0x69,0x64,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x65,0x6e,0x75,0x6d,0x20,0x42,0x6f,0x72,0x64,0x65,0x72,0x4d,0x6f,0x64,0x65,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x65,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x69,0x64,0x78,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x6c,0x69,0x63,0x65,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x72,0x69,0x64,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x72,0x69,0x64,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x67,0x72,0x69,0x64,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x72,0x69,0x64,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x73,0x6c,0x69,0x63,0x65,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x67,0x72,0x69,0x64,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x72,0x69,0x64,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x73,0x6c,0x69,0x63,0x65,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x61,0x72,0x72,0x5b,0x38,0x5d,0x20,0x3d,0x20,0x7b,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x78,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x79,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x7a,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x78,0x2e,0x77,0x2c,0x20,0x67,0x72,0x69,0x64,0x5f,0x79,0x2e,0x77,0x7d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x67,0x65,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x79,0x20,0x3d,0x20,0x61,0x72,0x72,0x5b,0x32,0x20,0x2a,0x20,0x61,0x72,0x72,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x20,0x67,0x72,0x69,0x64,0x20,0x78,0x2c,0x79,0x20,0x74,0x6f,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x63,0x6f,0x6f,0x72,0x64,0x69,0x6e,0x61,0x74,0x65,0x20,0x72,0x61,0x6e,0x67,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x28,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x43,0x6f,0x72,0x6e,0x65,0x72,0x73,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x30,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x30,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x6f,0x72,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x68,0x31,0x20,0x3d,0x20,0x63,0x65,0x69,0x6c,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x77,0x31,0x20,0x3d,0x20,0x63,0x65,0x69,0x6c,0x28,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x77,0x31,0x20,0x2d,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x79,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x68,0x31,0x20,0x2d,0x20,0x69,0x6e,0x5f,0x67,0x72,0x69,0x64,0x5f,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x30,0x30,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x30,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x30,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x69,0x6e,0x70,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x30,0x31,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x30,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x31,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x69,0x6e,0x70,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x31,0x30,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x31,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x30,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x69,0x6e,0x70,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x31,0x31,0x20,0x3d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x69,0x6e,0x5f,0x68,0x31,0x2c,0x20,0x69,0x6e,0x5f,0x77,0x31,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x69,0x6e,0x70,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x4d,0x6f,0x64,0x65,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x20,0x62,0x69,0x6c,0x69,0x6e,0x65,0x61,0x72,0x20,0x69,0x6e,0x74,0x65,0x72,0x70,0x6f,0x6c,0x61,0x74,0x69,0x6f,0x6e,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x30,0x30,0x29,0x20,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x66,0x20,0x2d,0x20,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x30,0x31,0x29,0x29,0x20,0x2a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x79,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x20,0x2b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x31,0x30,0x29,0x20,0x20,0x2b,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x66,0x20,0x2d,0x20,0x78,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x2a,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x69,0x31,0x31,0x29,0x29,0x20,0x2a,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x31,0x2e,0x30,0x66,0x2d,0x20,0x79,0x5f,0x77,0x65,0x69,0x67,0x68,0x74,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x77,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x68,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x7d,0xa, } - }, #ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "gemm_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x69,0x6e,0x64,0x65,0x78,0x30,0x2c,0x20,0x69,0x6e,0x64,0x65,0x78,0x31,0x29,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x6e,0x64,0x65,0x78,0x30,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x64,0x65,0x78,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x2f,0x2f,0x55,0x50,0x5f,0x44,0x49,0x56,0x28,0x77,0x55,0x6e,0x69,0x74,0x2a,0x68,0x55,0x6e,0x69,0x74,0x2c,0x34,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x2f,0x2f,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x70,0x68,0x61,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x70,0x6f,0x73,0x2e,0x78,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x79,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x5f,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x5f,0x79,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x6f,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x6e,0x65,0x72,0x6c,0x59,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x70,0x6f,0x73,0x5f,0x7a,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x70,0x6f,0x73,0x5f,0x79,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x48,0x57,0x43,0x20,0x20,0x5b,0x31,0x2c,0x20,0x31,0x2c,0x20,0x61,0x6c,0x70,0x68,0x61,0x32,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2a,0x34,0x5d,0x20,0x78,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x5b,0x30,0x2c,0x20,0x30,0x2c,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x2a,0x77,0x69,0x64,0x74,0x68,0x2b,0x70,0x6f,0x73,0x5f,0x79,0x2c,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2b,0x30,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x31,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6b,0x20,0x2a,0x20,0x28,0x61,0x6c,0x70,0x68,0x61,0x32,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x2b,0x20,0x6b,0x65,0x6e,0x65,0x72,0x6c,0x59,0x29,0x20,0x2a,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2a,0x34,0x29,0x20,0x2b,0x20,0x69,0x6e,0x64,0x65,0x78,0x29,0x2a,0x34,0x20,0x2b,0x20,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x6b,0x5f,0x76,0x31,0x36,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x65,0x6e,0x65,0x72,0x6c,0x59,0x2a,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x29,0x20,0x2b,0x20,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x61,0x6c,0x70,0x68,0x61,0x2a,0x61,0x6c,0x70,0x68,0x61,0x2c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x34,0x5d,0x20,0x78,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x70,0x6f,0x73,0x5f,0x7a,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x6f,0x73,0x5f,0x78,0x2c,0x20,0x30,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x28,0x28,0x70,0x6f,0x73,0x5f,0x7a,0x2a,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x6b,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x5f,0x78,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x34,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x38,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x63,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x2c,0x20,0x6f,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x35,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x39,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x64,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x2c,0x20,0x6f,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x36,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x61,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x65,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x2c,0x20,0x6f,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x66,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x2c,0x20,0x6f,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x70,0x6f,0x73,0x5f,0x79,0x2c,0x20,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x2c,0x20,0x20,0x30,0x2c,0x20,0x70,0x6f,0x73,0x5f,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x70,0x6f,0x73,0x5f,0x79,0x20,0x2a,0x20,0x61,0x6c,0x70,0x68,0x61,0x32,0x20,0x2b,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x5f,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x7d,0xa,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x32,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x2f,0x2f,0x55,0x50,0x5f,0x44,0x49,0x56,0x28,0x77,0x55,0x6e,0x69,0x74,0x2a,0x68,0x55,0x6e,0x69,0x74,0x2c,0x38,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x2f,0x2f,0x64,0x73,0x74,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x70,0x68,0x61,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x70,0x6f,0x73,0x2e,0x78,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x79,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x28,0x77,0x69,0x64,0x74,0x68,0x2b,0x31,0x29,0x20,0x3e,0x3e,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x5f,0x78,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x3c,0x3c,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x5f,0x79,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x6f,0x30,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x6f,0x31,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x6e,0x65,0x72,0x6c,0x59,0x20,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x70,0x6f,0x73,0x5f,0x7a,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x70,0x6f,0x73,0x5f,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x6d,0x75,0x6c,0x32,0x34,0x28,0x6b,0x65,0x6e,0x65,0x72,0x6c,0x59,0x2c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x5f,0x7a,0x2a,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x5f,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x20,0x3d,0x20,0x30,0x3b,0x20,0x6b,0x20,0x3c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x48,0x57,0x43,0x20,0x20,0x5b,0x31,0x2c,0x20,0x31,0x2c,0x20,0x61,0x6c,0x70,0x68,0x61,0x32,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2a,0x34,0x5d,0x20,0x78,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x5b,0x30,0x2c,0x20,0x30,0x2c,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x2a,0x77,0x69,0x64,0x74,0x68,0x2b,0x70,0x6f,0x73,0x5f,0x79,0x2c,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2b,0x30,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x31,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x6b,0x20,0x2a,0x20,0x28,0x61,0x6c,0x70,0x68,0x61,0x32,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x2b,0x20,0x6b,0x65,0x6e,0x65,0x72,0x6c,0x59,0x29,0x20,0x2a,0x20,0x28,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2a,0x34,0x29,0x20,0x2b,0x20,0x69,0x6e,0x64,0x65,0x78,0x29,0x2a,0x34,0x20,0x2b,0x20,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x6b,0x5f,0x76,0x31,0x36,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x6b,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x4e,0x43,0x34,0x48,0x57,0x34,0x20,0x5b,0x61,0x6c,0x70,0x68,0x61,0x2a,0x61,0x6c,0x70,0x68,0x61,0x2c,0x20,0x73,0x72,0x63,0x43,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x43,0x34,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x34,0x5d,0x20,0x78,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x70,0x6f,0x73,0x5f,0x7a,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6b,0x2c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x6f,0x73,0x5f,0x78,0x2c,0x20,0x30,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x6b,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x69,0x6e,0x70,0x5f,0x62,0x61,0x73,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x34,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x38,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x63,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x2c,0x20,0x6f,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x35,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x39,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x64,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x2c,0x20,0x6f,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x36,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x61,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x65,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x2c,0x20,0x6f,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x66,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x2c,0x20,0x6f,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x6e,0x70,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x34,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x38,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x63,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x2c,0x20,0x6f,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x35,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x39,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x64,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x2c,0x20,0x6f,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x36,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x61,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x65,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x2c,0x20,0x6f,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x2e,0x73,0x66,0x29,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6b,0x5f,0x76,0x31,0x36,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x2c,0x20,0x6f,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x20,0x5b,0x70,0x6f,0x73,0x5f,0x79,0x2c,0x20,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x2c,0x20,0x20,0x30,0x2c,0x20,0x70,0x6f,0x73,0x5f,0x78,0x5d,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x70,0x6f,0x73,0x5f,0x79,0x20,0x2a,0x20,0x61,0x6c,0x70,0x68,0x61,0x32,0x20,0x2b,0x20,0x70,0x6f,0x73,0x5f,0x7a,0x29,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x5f,0x78,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x30,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x30,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x30,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x30,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x5f,0x78,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x31,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x31,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x34,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x31,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x38,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x31,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x2c,0x20,0x31,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x2a,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0xa,0x7d,0xa,0xa,0x2f,0x2f,0x20,0x5b,0x4d,0x2c,0x20,0x4b,0x2f,0x34,0x2c,0x20,0x34,0x5d,0x20,0x2d,0x3e,0x20,0x5b,0x61,0x6c,0x69,0x67,0x6e,0x4b,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x5d,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x74,0x72,0x61,0x6e,0x73,0x70,0x6f,0x73,0x65,0x5f,0x70,0x61,0x64,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4d,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4b,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x5f,0x6d,0x34,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x69,0x64,0x78,0x20,0x4d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x5f,0x6b,0x34,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x69,0x64,0x78,0x20,0x4b,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x69,0x64,0x78,0x5f,0x6d,0x34,0x2c,0x20,0x69,0x64,0x78,0x5f,0x6b,0x34,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x3d,0x20,0x69,0x64,0x78,0x5f,0x6d,0x34,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x5f,0x6b,0x20,0x3d,0x20,0x69,0x64,0x78,0x5f,0x6b,0x34,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4b,0x5f,0x34,0x20,0x3d,0x20,0x28,0x4b,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x20,0x3d,0x20,0x28,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x4b,0x5f,0x34,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6b,0x34,0x29,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x3d,0x20,0x69,0x64,0x78,0x5f,0x6b,0x20,0x2a,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x30,0x6b,0x34,0x20,0x3d,0x20,0x28,0x69,0x64,0x78,0x5f,0x6b,0x34,0x20,0x3e,0x3d,0x20,0x4b,0x5f,0x34,0x20,0x7c,0x7c,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2b,0x20,0x30,0x20,0x3e,0x3d,0x20,0x4d,0x29,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x31,0x6b,0x34,0x20,0x3d,0x20,0x28,0x69,0x64,0x78,0x5f,0x6b,0x34,0x20,0x3e,0x3d,0x20,0x4b,0x5f,0x34,0x20,0x7c,0x7c,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x4d,0x29,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x28,0x4b,0x5f,0x34,0x20,0x3c,0x3c,0x20,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x32,0x6b,0x34,0x20,0x3d,0x20,0x28,0x69,0x64,0x78,0x5f,0x6b,0x34,0x20,0x3e,0x3d,0x20,0x4b,0x5f,0x34,0x20,0x7c,0x7c,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x4d,0x29,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x28,0x4b,0x5f,0x34,0x20,0x3c,0x3c,0x20,0x32,0x29,0x20,0x2a,0x20,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x33,0x6b,0x34,0x20,0x3d,0x20,0x28,0x69,0x64,0x78,0x5f,0x6b,0x34,0x20,0x3e,0x3d,0x20,0x4b,0x5f,0x34,0x20,0x7c,0x7c,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x4d,0x29,0x20,0x3f,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x69,0x6e,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x28,0x4b,0x5f,0x34,0x20,0x3c,0x3c,0x20,0x32,0x29,0x20,0x2a,0x20,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x6d,0x30,0x6b,0x34,0x2e,0x78,0x2c,0x20,0x6d,0x31,0x6b,0x34,0x2e,0x78,0x2c,0x20,0x6d,0x32,0x6b,0x34,0x2e,0x78,0x2c,0x20,0x6d,0x33,0x6b,0x34,0x2e,0x78,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x6d,0x30,0x6b,0x34,0x2e,0x79,0x2c,0x20,0x6d,0x31,0x6b,0x34,0x2e,0x79,0x2c,0x20,0x6d,0x32,0x6b,0x34,0x2e,0x79,0x2c,0x20,0x6d,0x33,0x6b,0x34,0x2e,0x79,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x6d,0x30,0x6b,0x34,0x2e,0x7a,0x2c,0x20,0x6d,0x31,0x6b,0x34,0x2e,0x7a,0x2c,0x20,0x6d,0x32,0x6b,0x34,0x2e,0x7a,0x2c,0x20,0x6d,0x33,0x6b,0x34,0x2e,0x7a,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x6d,0x30,0x6b,0x34,0x2e,0x77,0x2c,0x20,0x6d,0x31,0x6b,0x34,0x2e,0x77,0x2c,0x20,0x6d,0x32,0x6b,0x34,0x2e,0x77,0x2c,0x20,0x6d,0x33,0x6b,0x34,0x2e,0x77,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x62,0x61,0x73,0x65,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x20,0x2b,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x29,0x3b,0xa,0x7d,0xa,0xa,0x2f,0x2f,0x20,0x5b,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x2c,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4e,0x5d,0x20,0x2d,0x3e,0x20,0x5b,0x4d,0x2c,0x20,0x4e,0x2f,0x34,0x2c,0x20,0x34,0x5d,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x61,0x64,0x64,0x5f,0x62,0x69,0x61,0x73,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x44,0x49,0x4d,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4d,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4e,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4d,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4e,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x69,0x64,0x78,0x20,0x4d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x69,0x64,0x78,0x20,0x4e,0xa,0x20,0x20,0x20,0x20,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x42,0x4f,0x55,0x4e,0x44,0x52,0x59,0x5f,0x43,0x48,0x45,0x43,0x4b,0x28,0x69,0x64,0x78,0x5f,0x6d,0x2c,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4e,0x5f,0x31,0x36,0x20,0x3d,0x20,0x28,0x4e,0x20,0x2b,0x20,0x31,0x35,0x29,0x20,0x3e,0x3e,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4e,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x20,0x4e,0x20,0x26,0x20,0x31,0x35,0x3b,0xa,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x63,0x61,0x6e,0x56,0x65,0x63,0x31,0x36,0x20,0x3d,0x20,0x28,0x4e,0x5f,0x6c,0x65,0x66,0x74,0x20,0x3d,0x3d,0x20,0x30,0x20,0x7c,0x7c,0x20,0x28,0x4e,0x5f,0x6c,0x65,0x66,0x74,0x20,0x21,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x20,0x4e,0x5f,0x31,0x36,0x20,0x2d,0x20,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x61,0x6e,0x56,0x65,0x63,0x31,0x36,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x72,0x65,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4e,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x72,0x65,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x72,0x65,0x73,0x30,0x20,0x2b,0x20,0x72,0x65,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x31,0x36,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x28,0x28,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x4e,0x5f,0x31,0x36,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x29,0x20,0x3c,0x3c,0x20,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x4e,0x5f,0x34,0x20,0x3d,0x20,0x28,0x4e,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4e,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x72,0x65,0x73,0x30,0x20,0x2b,0x20,0x72,0x65,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x28,0x28,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x4e,0x5f,0x31,0x36,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x29,0x20,0x3c,0x3c,0x20,0x34,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x4e,0x5f,0x34,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4e,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x72,0x65,0x73,0x30,0x20,0x2b,0x20,0x72,0x65,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x28,0x28,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x4e,0x5f,0x31,0x36,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x29,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x4e,0x5f,0x34,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4e,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x72,0x65,0x73,0x30,0x20,0x2b,0x20,0x72,0x65,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x28,0x28,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x4e,0x5f,0x31,0x36,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x29,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x38,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x4e,0x5f,0x34,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x61,0x6c,0x69,0x67,0x6e,0x4e,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x28,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x72,0x65,0x73,0x30,0x20,0x2b,0x20,0x72,0x65,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x28,0x28,0x69,0x64,0x78,0x5f,0x6d,0x20,0x2a,0x20,0x4e,0x5f,0x31,0x36,0x20,0x2b,0x20,0x69,0x64,0x78,0x5f,0x6e,0x5f,0x31,0x36,0x29,0x20,0x3c,0x3c,0x20,0x34,0x29,0x20,0x2b,0x20,0x31,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, +const char* select_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__kernel void select_buf(GLOBAL_SIZE_2_DIMS\n" +" __global const int* select,\n" +" __global const FLOAT* input0,\n" +" __global const FLOAT* input1,\n" +" __global FLOAT* output\n" +" ) {\n" +" const int idx=get_global_id(0);\n" +" const int idy=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(idx,idy);\n" +" if (select[idx]) {\n" +"#ifdef INSIZE1_EUQAL_1\n" +" output[idx]=input0[0];\n" +"#else\n" +" output[idx]=input0[idx];\n" +"#endif\n" +" } else {\n" +"#ifdef INSIZE2_EUQAL_1\n" +" output[idx]=input1[0];\n" +"#else\n" +" output[idx]=input1[idx];\n" +"#endif\n" +" }\n" +"}\n" +; #endif -{ - "copy_buffer_to_image2d", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6f,0x70,0x79,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x5f,0x74,0x6f,0x5f,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x28,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x55,0x46,0x46,0x45,0x52,0x5f,0x49,0x4e,0x50,0x5f,0x46,0x50,0x33,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x78,0x20,0x3c,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x26,0x26,0x20,0x79,0x20,0x3c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x75,0x4f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x78,0x2c,0x20,0x79,0x29,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5d,0x2e,0x78,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5d,0x2e,0x79,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5d,0x2e,0x7a,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5d,0x2e,0x77,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } - }, -{ - "loop", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x49,0x20,0x33,0x2e,0x31,0x34,0x31,0x35,0x39,0x32,0x36,0x35,0x33,0x35,0x38,0x39,0x66,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x74,0x65,0x72,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x65,0x70,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x3c,0x3d,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x3d,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x7a,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x7a,0x20,0x3d,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x77,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x77,0x20,0x3d,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x77,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x5f,0x70,0x61,0x63,0x6b,0x20,0x3d,0x20,0x28,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6c,0x5f,0x70,0x61,0x63,0x6b,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x3b,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x28,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x28,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x28,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x65,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x6c,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x6c,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6c,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x6c,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x6c,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x30,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x31,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x32,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x33,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x30,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x31,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x32,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x33,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x30,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x31,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x32,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x33,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x30,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x31,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x32,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x74,0x6d,0x70,0x33,0x2e,0x77,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x28,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x28,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x28,0x6c,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x30,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x31,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x32,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x30,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x31,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x32,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x33,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x33,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x28,0x28,0x6c,0x5f,0x70,0x61,0x63,0x6b,0x20,0x2d,0x20,0x31,0x29,0x20,0x3c,0x3c,0x20,0x32,0x29,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6c,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x65,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x78,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x79,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2b,0x20,0x6c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x7a,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x6c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x77,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x6c,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2e,0x78,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2e,0x79,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2b,0x20,0x6c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2e,0x7a,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x6c,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2e,0x77,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x6c,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x78,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x79,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x7a,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2e,0x77,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x23,0x69,0x66,0x20,0x48,0x5f,0x4c,0x45,0x41,0x56,0x45,0x53,0x20,0x3d,0x3d,0x20,0x30,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2b,0x20,0x33,0x20,0x3c,0x20,0x68,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x30,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x31,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x32,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x33,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x23,0x69,0x66,0x20,0x48,0x5f,0x4c,0x45,0x41,0x56,0x45,0x53,0x20,0x3d,0x3d,0x20,0x31,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x30,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x31,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x32,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x33,0x2e,0x78,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x48,0x5f,0x4c,0x45,0x41,0x56,0x45,0x53,0x20,0x3d,0x3d,0x20,0x32,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x76,0x61,0x6c,0x75,0x65,0x30,0x2e,0x78,0x79,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x76,0x61,0x6c,0x75,0x65,0x31,0x2e,0x78,0x79,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x76,0x61,0x6c,0x75,0x65,0x32,0x2e,0x78,0x79,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x32,0x29,0x76,0x61,0x6c,0x75,0x65,0x33,0x2e,0x78,0x79,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x23,0x65,0x6c,0x69,0x66,0x20,0x48,0x5f,0x4c,0x45,0x41,0x56,0x45,0x53,0x20,0x3d,0x3d,0x20,0x33,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x33,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x33,0x29,0x76,0x61,0x6c,0x75,0x65,0x30,0x2e,0x78,0x79,0x7a,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x33,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x33,0x29,0x76,0x61,0x6c,0x75,0x65,0x31,0x2e,0x78,0x79,0x7a,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x33,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x33,0x29,0x76,0x61,0x6c,0x75,0x65,0x32,0x2e,0x78,0x79,0x7a,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x32,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x65,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x33,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x33,0x29,0x76,0x61,0x6c,0x75,0x65,0x33,0x2e,0x78,0x79,0x7a,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x33,0x20,0x2a,0x20,0x68,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x74,0x69,0x6c,0x65,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x4e,0x48,0x57,0x43,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x34,0x28,0x52,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x30,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x32,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x33,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x61,0x63,0x6b,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x4e,0x48,0x57,0x43,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x20,0x2a,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x2a,0x29,0x26,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x20,0x26,0x26,0x20,0x28,0x69,0x20,0x2b,0x20,0x63,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x5f,0x49,0x29,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x67,0x61,0x74,0x68,0x65,0x72,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x49,0x4e,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x65,0x70,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x74,0x65,0x72,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x69,0x7a,0x65,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x20,0x26,0x26,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x3c,0x20,0x69,0x6e,0x70,0x75,0x74,0x53,0x69,0x7a,0x65,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x7a,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x65,0x6c,0x73,0x65,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x7a,0x5d,0x20,0x3d,0x20,0x28,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x54,0x59,0x50,0x45,0x29,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4c,0x4f,0x4f,0x50,0x5f,0x42,0x49,0x4e,0x41,0x52,0x59,0x5f,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x72,0x6f,0x61,0x64,0x63,0x61,0x73,0x74,0x5f,0x62,0x69,0x6e,0x61,0x72,0x79,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x38,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x20,0x2f,0x2f,0x28,0x62,0x61,0x74,0x63,0x68,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x20,0x2f,0x2f,0x20,0x6e,0x63,0x34,0x68,0x77,0x34,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x38,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x38,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x6f,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x6f,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x6f,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x25,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x6f,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2f,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x6f,0x34,0x20,0x3d,0x20,0x63,0x6f,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x6f,0x76,0x65,0x63,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x63,0x6f,0x34,0x20,0x25,0x20,0x64,0x73,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0x20,0x28,0x63,0x6f,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x25,0x20,0x64,0x73,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0x20,0x28,0x63,0x6f,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x25,0x20,0x64,0x73,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0x20,0x28,0x63,0x6f,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x25,0x20,0x64,0x73,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6e,0x6f,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x63,0x6f,0x76,0x65,0x63,0x29,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x6f,0x29,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x6f,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x77,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x28,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x33,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x34,0x29,0x3b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x28,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x33,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x68,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x32,0x3b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x31,0x3b,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6e,0x20,0x3d,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x64,0x73,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x20,0x69,0x6e,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x26,0x69,0x6e,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x20,0x69,0x6e,0x31,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x26,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x77,0x30,0x20,0x3d,0x20,0x77,0x20,0x25,0x20,0x28,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x33,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x68,0x30,0x20,0x3d,0x20,0x68,0x20,0x25,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x30,0x20,0x3d,0x20,0x63,0x20,0x25,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6e,0x30,0x20,0x3d,0x20,0x6e,0x20,0x25,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x77,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x77,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x68,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x68,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x63,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x63,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6e,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x6e,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6e,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x31,0x20,0x2b,0x20,0x63,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x32,0x20,0x2b,0x20,0x68,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x33,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x34,0x20,0x2b,0x20,0x77,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x3b,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6e,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x63,0x34,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x63,0x63,0x34,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x63,0x34,0x5f,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x63,0x63,0x34,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x74,0x6d,0x70,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x52,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x63,0x34,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x63,0x34,0x2c,0x20,0x6e,0x63,0x34,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x63,0x34,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x26,0x74,0x6d,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x5b,0x63,0x63,0x34,0x5f,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x77,0x30,0x20,0x3d,0x20,0x77,0x20,0x25,0x20,0x28,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x33,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x68,0x30,0x20,0x3d,0x20,0x68,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x30,0x20,0x3d,0x20,0x63,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6e,0x30,0x20,0x3d,0x20,0x6e,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x77,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x77,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x68,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x68,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x63,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x63,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6e,0x30,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x6e,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x6e,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x31,0x20,0x2b,0x20,0x63,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x32,0x20,0x2b,0x20,0x68,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x33,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x73,0x34,0x20,0x2b,0x20,0x77,0x30,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x68,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x3b,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2f,0x3d,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6e,0x63,0x34,0x20,0x3d,0x20,0x63,0x34,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x63,0x34,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x63,0x63,0x34,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x63,0x34,0x5f,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x63,0x63,0x34,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x74,0x6d,0x70,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x52,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x63,0x34,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x63,0x34,0x2c,0x20,0x6e,0x63,0x34,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x43,0x34,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x63,0x34,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x2a,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x26,0x74,0x6d,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x5b,0x63,0x63,0x34,0x5f,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x4c,0x4f,0x4f,0x50,0x5f,0x42,0x49,0x4e,0x41,0x52,0x59,0x5f,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x44,0x41,0x54,0x41,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x6f,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x6f,0x2c,0x20,0x6e,0x6f,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x6f,0x29,0x2c,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x5f,0x49,0x34,0x28,0x6f,0x75,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa, } - }, +const char* grid_sample = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"enum BorderMode {\n" +" BorderMode_ZEROS=0,\n" +" BorderMode_CLAMP=1,\n" +" BorderMode_REFLECTION=2,\n" +" BorderMode_MIN=BorderMode_ZEROS,\n" +" BorderMode_MAX=BorderMode_REFLECTION\n" +"};\n" +"float getPosition(float x,int range,int alignCorners){\n" +" float a=alignCorners == 1? 1.0f : 0.0f;\n" +" float b=alignCorners == 1? 0.0f : 1.0f;\n" +" return ((1+x)*(range-a)-b)/2.0f;\n" +"}\n" +"static int CLAMP(int v,int min,int max) {\n" +" if ((v)max) {\n" +" (v)=max;\n" +" }\n" +" return v;\n" +"}\n" +"FLOAT4 sample(int h,int w,\n" +" const int w_offset_base,\n" +" const int h_offset_base,\n" +" __read_only image2d_t tmp,\n" +" int height,int width,\n" +" enum BorderMode paddingMode){\n" +" if (h<0 || h >= height || w<0 || w >= width) {\n" +" if(paddingMode == BorderMode_ZEROS)\n" +" {\n" +" return 0.0f;\n" +" }\n" +" // Clearly,CLAMP is the right way to go for GridSamplePaddingMode_BORDER\n" +" // For GridSamplePaddingMode_REFLECTION,since we have reflected the values into (-1,1),\n" +" // the leftover reflections degrade to GridSamplePaddingMode_BORDER\n" +" h=CLAMP(h,0,height-1);\n" +" w=CLAMP(w,0,width-1);\n" +" }\n" +" return RI_F(tmp,SAMPLER,(int2)(w_offset_base+w,h_offset_base+h));\n" +"}\n" +"__kernel void nearest(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,\n" +" __read_only image2d_t grid,\n" +" __write_only image2d_t output,\n" +" __private const int input_height,\n" +" __private const int input_width,\n" +" __private const int output_height,\n" +" __private const int output_width,\n" +" __private const enum BorderMode paddingMode,\n" +" __private const int alignCorners\n" +" ){\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" const int output_batch_idx=output_batch_height_block_idx/output_height;\n" +" const int output_height_idx=output_batch_height_block_idx % output_height;\n" +" // grid data format has been converted from nchw to nc4hw4\n" +" /* slice slice\n" +" (x1,y1)...(xn,y1) (x1,x1,x1,x1) (y1,y2,y3,y4) | (x1,x1,x1,x1) (y5,y6,y7,y8) | ... \n" +" . . . . | . . |\n" +" . . <-> . . | . . |\n" +" . . . . | . . |\n" +" (x1,ym)...(xn,ym) (xn,xn,xn,xn) (y1,y2,y3,y4) | (xn,xn,xn,xn) (y5,y6,y7,y8) | ...\n" +" */\n" +" const int slice=output_height_idx/4;\n" +" const int grid_w_offset=0;\n" +" const int grid_h_offset=mad24(output_batch_idx,output_width,output_width_block_idx);\n" +" \n" +" FLOAT4 grid_x=RI_F(grid,SAMPLER,(int2)(grid_w_offset+2*slice,grid_h_offset));\n" +" FLOAT4 grid_y=RI_F(grid,SAMPLER,(int2)(grid_w_offset+1+2*slice,grid_h_offset));\n" +" const float arr[8]={grid_x.x,grid_y.x,grid_x.y,grid_y.y,grid_x.z,grid_y.z,grid_x.w,grid_y.w};\n" +" \n" +" // get grid x,y\n" +" const int arr_offset=output_height_idx % 4;\n" +" const float x=arr[2*arr_offset];\n" +" const float y=arr[2*arr_offset+1];\n" +" // convert grid x,y to input coordinate range\n" +" float in_grid_x=getPosition(x,input_width,alignCorners);\n" +" float in_grid_y=getPosition(y,input_height,alignCorners);\n" +" // get nearest point\n" +" int nw=floor(in_grid_x+0.5f);\n" +" int nh=floor(in_grid_y+0.5f);\n" +" const int inp_w_offset=mul24(output_channel_block_idx,input_width);\n" +" const int inp_h_offset=mul24(output_batch_idx,input_height);\n" +" FLOAT4 value=sample(nh,nw,inp_w_offset,inp_h_offset,input,input_height,input_width,paddingMode);\n" +" const int output_w_offset=mad24(output_channel_block_idx,output_width,output_width_block_idx);\n" +" const int output_h_offset=mad24(output_batch_idx,output_height,output_height_idx);\n" +" WI_F(output,(int2)(output_w_offset,output_h_offset),value);\n" +"}\n" +"__kernel void bilinear(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,\n" +" __read_only image2d_t grid,\n" +" __write_only image2d_t output,\n" +" __private const int input_height,\n" +" __private const int input_width,\n" +" __private const int output_height,\n" +" __private const int output_width,\n" +" __private const enum BorderMode paddingMode,\n" +" __private const int alignCorners\n" +" ){\n" +" const int output_channel_block_idx=get_global_id(0);\n" +" const int output_width_block_idx=get_global_id(1);\n" +" const int output_batch_height_block_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_block_idx,output_width_block_idx,output_batch_height_block_idx);\n" +" const int output_batch_idx=output_batch_height_block_idx/output_height;\n" +" const int output_height_idx=output_batch_height_block_idx % output_height;\n" +" // get grid idx\n" +" const int slice=output_height_idx/4;\n" +" const int grid_w_offset=0;\n" +" const int grid_h_offset=mad24(output_batch_idx,output_width,output_width_block_idx);\n" +" \n" +" FLOAT4 grid_x=RI_F(grid,SAMPLER,(int2)(grid_w_offset+2*slice,grid_h_offset));\n" +" FLOAT4 grid_y=RI_F(grid,SAMPLER,(int2)(grid_w_offset+1+2*slice,grid_h_offset));\n" +" const float arr[8]={grid_x.x,grid_y.x,grid_x.y,grid_y.y,grid_x.z,grid_y.z,grid_x.w,grid_y.w};\n" +" \n" +" // get grid x,y\n" +" const int arr_offset=output_height_idx % 4;\n" +" const float x=arr[2*arr_offset];\n" +" const float y=arr[2*arr_offset+1];\n" +" // convert grid x,y to input coordinate range\n" +" float in_grid_x=getPosition(x,input_width,alignCorners);\n" +" float in_grid_y=getPosition(y,input_height,alignCorners);\n" +" int in_h0=floor(in_grid_y);\n" +" int in_w0=floor(in_grid_x);\n" +" int in_h1=ceil(in_grid_y);\n" +" int in_w1=ceil(in_grid_x);\n" +" float x_weight=in_w1-in_grid_x;\n" +" float y_weight=in_h1-in_grid_y;\n" +" const int inp_w_offset=mul24(output_channel_block_idx,input_width);\n" +" const int inp_h_offset=mul24(output_batch_idx,input_height);\n" +" FLOAT4 i00=sample(in_h0,in_w0,inp_w_offset,inp_h_offset,input,input_height,input_width,paddingMode);\n" +" FLOAT4 i01=sample(in_h0,in_w1,inp_w_offset,inp_h_offset,input,input_height,input_width,paddingMode);\n" +" FLOAT4 i10=sample(in_h1,in_w0,inp_w_offset,inp_h_offset,input,input_height,input_width,paddingMode);\n" +" FLOAT4 i11=sample(in_h1,in_w1,inp_w_offset,inp_h_offset,input,input_height,input_width,paddingMode);\n" +" // bilinear interpolation\n" +" FLOAT4 value=CONVERT_FLOAT4(((FLOAT4)x_weight*CONVERT_FLOAT4(i00)+(FLOAT4)(1.0f-x_weight)*CONVERT_FLOAT4(i01))*(FLOAT4)y_weight +\n" +" ((FLOAT4)x_weight*CONVERT_FLOAT4(i10)+(FLOAT4)(1.0f-x_weight)*CONVERT_FLOAT4(i11))*(FLOAT4)(1.0f- y_weight));\n" +" const int output_w_offset=mad24(output_channel_block_idx,output_width,output_width_block_idx);\n" +" const int output_h_offset=mad24(output_batch_idx,output_height,output_height_idx);\n" +" WI_F(output,(int2)(output_w_offset,output_h_offset),value);\n" +"}\n" +; +const char* buffer_convert_quant = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"#ifdef USE_LOW_BIT_WEIGHT_INT8\n" +"// convert kernel : from int8 buffer(oihw) to int8 image(oc/4 h w ,ic oc4)\n" +"__kernel void conv2d_filter_buffer_to_nc4hw4_buffer_int8(GLOBAL_SIZE_2_DIMS\n" +" __global const char *input_ptr,\n" +" __private const int output_channel,\n" +" __private const int2 kernel_shape,\n" +" __private const int ic_h_w_size,\n" +" __private const int height_width_size,\n" +" __global char *output) {\n" +" int image_width_idx=get_global_id(0); // ic\n" +" int image_height_idx=get_global_id(1); // oc/4 h w\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" \n" +" const int input_channel_4_idx=image_width_idx;\n" +" const int output_channel_4_idx=(image_height_idx/height_width_size)*4;\n" +" const int height_width_idx=image_height_idx % height_width_size;\n" +" const int buffer_height_idx=height_width_idx/kernel_shape.y;\n" +" const int buffer_width_idx=height_width_idx % kernel_shape.y;\n" +" \n" +" const int buffer_offset=output_channel_4_idx*ic_h_w_size+input_channel_4_idx*height_width_size +\n" +" buffer_height_idx*kernel_shape.y+buffer_width_idx;\n" +" \n" +" char4 output_values=0;\n" +" if (output_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(char)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(char)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(char)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.w=(char)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(char)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(char)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(char)(*(input_ptr+offset));\n" +" \n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(char)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(char)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(char)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" const int out_offset=(image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*4;\n" +" vstore4(output_values,0,output+out_offset);\n" +"}\n" +"#endif\n" +"#ifdef USE_LOW_BIT_WEIGHT_INT4\n" +"// convert kernel : from int8 buffer(oihw) to int4 image(oc/4 h w ,ic oc4)\n" +"__kernel void conv2d_filter_buffer_to_nc4hw4_buffer_int4(GLOBAL_SIZE_2_DIMS\n" +" __global const char *input_ptr,\n" +" __private const int output_channel,\n" +" __private const int2 kernel_shape,\n" +" __private const int ic_h_w_size,\n" +" __private const int height_width_size,\n" +" __global uchar *output) {\n" +" int image_width_idx=get_global_id(0); // ic\n" +" int image_height_idx=get_global_id(1); // oc/4 h w\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" \n" +" const int input_channel_4_idx=image_width_idx;\n" +" const int output_channel_4_idx=(image_height_idx/height_width_size)*4;\n" +" const int height_width_idx=image_height_idx % height_width_size;\n" +" const int buffer_height_idx=height_width_idx/kernel_shape.y;\n" +" const int buffer_width_idx=height_width_idx % kernel_shape.y;\n" +" \n" +" const int buffer_offset=output_channel_4_idx*ic_h_w_size+input_channel_4_idx*height_width_size +\n" +" buffer_height_idx*kernel_shape.y+buffer_width_idx;\n" +" \n" +" char4 output_values_int8=0;\n" +" if (output_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values_int8.x=(char)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values_int8.y=(char)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values_int8.z=(char)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values_int8.w=(char)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values_int8.x=(char)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values_int8.y=(char)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values_int8.z=(char)(*(input_ptr+offset));\n" +" \n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values_int8.x=(char)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values_int8.y=(char)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values_int8.x=(char)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" \n" +" uchar2 output_values_int4=(uchar2)(0,0);\n" +" output_values_int4.s0=(output_values_int8.x+8)*16+(output_values_int8.y+8);\n" +" output_values_int4.s1=(output_values_int8.z+8)*16+(output_values_int8.w+8);\n" +" \n" +" const int out_offset=(image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*2;\n" +" vstore2(output_values_int4,0,output+out_offset);\n" +"}\n" +"#endif\n" +"#define CHAR16_TO_UCHAR8(a, b) "" a=(uchar8)(((b.s0+8) << 4)+b.s1+8,((b.s2+8) << 4)+b.s3+8,((b.s4+8) << 4)+b.s5+8,((b.s6+8) << 4)+b.s7+8,((b.s8+8) << 4)+b.s9+8,((b.sa+8) << 4)+b.sb+8,((b.sc+8) << 4)+b.sd+8,((b.se+8) << 4)+b.sf+8);\n" +"#define CHAR32_TO_UCHAR16(a, b, c) "" a = (uchar16)(((b.s0 + 8) << 4) + b.s1 + 8, ((b.s2 + 8) << 4) + b.s3 + 8, ((b.s4 + 8) << 4) + b.s5 + 8, ((b.s6 + 8) << 4) + b.s7 + 8, ((b.s8 + 8) << 4) + b.s9 + 8, ((b.sa + 8) << 4) + b.sb + 8, ((b.sc + 8) << 4) + b.sd + 8, ((b.se + 8) << 4) + b.sf + 8, "" ((c.s0+8) << 4)+c.s1+8,((c.s2+8) << 4)+c.s3+8,((c.s4+8) << 4)+c.s5+8,((c.s6+8) << 4)+c.s7+8,((c.s8+8) << 4)+c.s9+8,((c.sa+8) << 4)+c.sb+8,((c.sc+8) << 4)+c.sd+8,((c.se+8) << 4)+c.sf+8);\n" +"__kernel void conv2d_1x1_weight_quant_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global const char *input_ptr,\n" +"#ifdef USE_LOW_BIT_WEIGHT_INT4\n" +" __global uchar *output_ptr,\n" +"#else\n" +" __global char *output_ptr,\n" +"#endif\n" +" __private const int input_channel,\n" +" __private const int output_channel) {\n" +" int x=get_global_id(0); // ic/16\n" +" int y=get_global_id(1); // oc\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(x,y);\n" +" const int xin=x << 4;\n" +" const int outputChannelC4=(output_channel+3) >> 2;\n" +" const int inputOffset=y*input_channel+xin;\n" +" char16 weight=0;\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" if(xin+15 >= input_channel){\n" +" char *weight_ptr=(char*)&weight;\n" +" for(int i=0,j=0; xin+i> 2;\n" +" const int xin=x << 5;\n" +" const int inputOffset=y*input_channel+xin;\n" +" char16 weight00=0,weight01=0;\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" if(xin+31 >= input_channel){\n" +" char *weight00_ptr=(char*)&weight00;\n" +" char *weight01_ptr=(char*)&weight01;\n" +" int i=0;\n" +" for(int j=0; xin+i> 2;\n" +" char16 weight=0;\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" if(xin+15 >= input_channel){\n" +" char *weight_ptr=(char*)&weight;\n" +" for(int i=0,j=0; xin+i= global_size_dim0 || index1 >= global_size_dim1) { "" return; "" }\n" +"__kernel void gemm_buf(GLOBAL_SIZE_DIM2\n" +" __global const FLOAT* input0,\n" +" __global const FLOAT* input1,\n" +" __global FLOAT* output,\n" +" __private const int width,//UP_DIV(wUnit*hUnit,4)\n" +" __private const int height,//dstChannelC4\n" +" __private const int srcChannelC4,\n" +" __private const int alpha2) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" const int pos_x=pos.x % width;\n" +" const int pos_y=pos.x/width;\n" +" const int pos_z=pos.y;\n" +" COMPUTE_FLOAT16 o=(COMPUTE_FLOAT16)0;\n" +" \n" +" int kenerlY=mad24(pos_z,height,pos_y);\n" +" for (int k=0; k> 1;\n" +" const int pos_x=(pos.x % width_block) << 1;\n" +" const int pos_y=pos.x/width_block;\n" +" const int pos_z=pos.y;\n" +" COMPUTE_FLOAT16 o0=(COMPUTE_FLOAT16)0;\n" +" COMPUTE_FLOAT16 o1=(COMPUTE_FLOAT16)0;\n" +" const int kenerlY=mad24(pos_z,height,pos_y);\n" +" const int kernel_base=mul24(kenerlY,srcChannelC4);\n" +" const int inp_base=(pos_z*srcChannelC4+0)*width+pos_x;\n" +" \n" +" for (int k=0; k= width) return;\n" +" vstore4(CONVERT_FLOAT4(o1.s0123),1,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(o1.s4567),1,output+out_offset+4*width);\n" +" vstore4(CONVERT_FLOAT4(o1.s89ab),1,output+out_offset+8*width);\n" +" vstore4(CONVERT_FLOAT4(o1.scdef),1,output+out_offset+12*width);\n" +"}\n" +"// [M,K/4,4] -> [alignK,alignM]\n" +"__kernel void transpose_pad(GLOBAL_SIZE_DIM2\n" +" const int alignM,\n" +" const int alignK,\n" +" const int M,\n" +" const int K,\n" +" __global const FLOAT* input,\n" +" __global FLOAT* output\n" +" ) {\n" +" const int idx_m4=get_global_id(0); // idx M\n" +" const int idx_k4=get_global_id(1); // idx K\n" +" UNIFORM_BOUNDRY_CHECK(idx_m4,idx_k4);\n" +" const int idx_m=idx_m4 << 2;\n" +" const int idx_k=idx_k4 << 2;\n" +" const int K_4=(K+3) >> 2;\n" +" const int in_offset_base=(idx_m*K_4+idx_k4)*4;\n" +" const int out_offset_base=idx_k*alignM+idx_m;\n" +" \n" +" FLOAT4 m0k4=(idx_k4 >= K_4 || idx_m+0 >= M) ? (FLOAT4)0 : vload4(0,input+in_offset_base);\n" +" FLOAT4 m1k4=(idx_k4 >= K_4 || idx_m+1 >= M) ? (FLOAT4)0 : vload4(0,input+in_offset_base+(K_4 << 2));\n" +" FLOAT4 m2k4=(idx_k4 >= K_4 || idx_m+2 >= M) ? (FLOAT4)0 : vload4(0,input+in_offset_base+(K_4 << 2)*2);\n" +" FLOAT4 m3k4=(idx_k4 >= K_4 || idx_m+3 >= M) ? (FLOAT4)0 : vload4(0,input+in_offset_base+(K_4 << 2)*3);\n" +" \n" +" vstore4((FLOAT4)(m0k4.x,m1k4.x,m2k4.x,m3k4.x),0,output+out_offset_base);\n" +" vstore4((FLOAT4)(m0k4.y,m1k4.y,m2k4.y,m3k4.y),0,output+out_offset_base+alignM);\n" +" vstore4((FLOAT4)(m0k4.z,m1k4.z,m2k4.z,m3k4.z),0,output+out_offset_base+alignM+alignM);\n" +" vstore4((FLOAT4)(m0k4.w,m1k4.w,m2k4.w,m3k4.w),0,output+out_offset_base+alignM+alignM+alignM);\n" +"}\n" +"// [alignM,alignN] -> [M,N/4,4]\n" +"__kernel void add_bias(GLOBAL_SIZE_DIM2\n" +" const int alignM,\n" +" const int alignN,\n" +" const int M,\n" +" const int N,\n" +" __global const FLOAT* input0,\n" +" __global const FLOAT* input1,\n" +" __global FLOAT* output\n" +" ) {\n" +" const int idx_m=get_global_id(0); // idx M\n" +" const int idx_n_16=get_global_id(1); // idx N\n" +" UNIFORM_BOUNDRY_CHECK(idx_m,idx_n_16);\n" +" const int N_16=(N+15) >> 4;\n" +" const int N_left=N & 15;\n" +" bool canVec16=(N_left == 0 || (N_left != 0 && idx_n_16> 2;\n" +" FLOAT4 res0=vload4(0,input0+idx_m*alignN+(idx_n_16 << 4));\n" +" FLOAT4 res1=vload4(0,input1+(idx_n_16 << 4));\n" +" FLOAT4 res=res0+res1;\n" +" vstore4(res,0,output+((idx_m*N_16+idx_n_16) << 4));\n" +" \n" +" if(idx_n_16*4+1 >= N_4) return;\n" +" res0=vload4(0,input0+idx_m*alignN+(idx_n_16 << 4)+4);\n" +" res1=vload4(0,input1+(idx_n_16 << 4)+4);\n" +" res=res0+res1;\n" +" vstore4(res,0,output+((idx_m*N_16+idx_n_16) << 4)+4);\n" +" \n" +" if(idx_n_16*4+2 >= N_4) return;\n" +" res0=vload4(0,input0+idx_m*alignN+(idx_n_16 << 4)+8);\n" +" res1=vload4(0,input1+(idx_n_16 << 4)+8);\n" +" res=res0+res1;\n" +" vstore4(res,0,output+((idx_m*N_16+idx_n_16) << 4)+8);\n" +" \n" +" if(idx_n_16*4+3 >= N_4) return;\n" +" res0=vload4(0,input0+idx_m*alignN+(idx_n_16 << 4)+12);\n" +" res1=vload4(0,input1+(idx_n_16 << 4)+12);\n" +" res=res0+res1;\n" +" vstore4(res,0,output+((idx_m*N_16+idx_n_16) << 4)+12);\n" +" }\n" +"}\n" +; +#endif +const char* copy_buffer_to_image2d = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void copy_buffer_to_image2d(\n" +" #ifdef BUFFER_INP_FP32\n" +" __global const float4* input,\n" +" #else\n" +" __global const FLOAT4* input,\n" +" #endif\n" +" __write_only image2d_t uOutput,\n" +" __private const int width,__private const int height) {\n" +" int x=get_global_id(0);\n" +" int y=get_global_id(1);\n" +" if (x= 0) {\n" +" index.x=offset_O[pos.z];\n" +" }\n" +" if (iters.y >= 0) {\n" +" index.y=offset_A[pos.z];\n" +" }\n" +" if (iters.z >= 0) {\n" +" index.z=offset_B[pos.z];\n" +" }\n" +"#ifdef BIAS\n" +" if (iters.w >= 0) {\n" +" index.w=offset_C[pos.z];\n" +" }\n" +"#endif\n" +" int4 offset=index*steps+offsets;\n" +" \n" +"#if TRANSPOSE_A\n" +" __global FLOAT* A_ptr=input_A+offset.y+pos.y;\n" +"#else\n" +" __global FLOAT* A_ptr=input_A+offset.y+pos.y*l;\n" +"#endif\n" +"#if TRANSPOSE_B\n" +" __global FLOAT* B_ptr=input_B+offset.z+pos.x*l;\n" +"#else\n" +" __global FLOAT* B_ptr=input_B+offset.z+pos.x;\n" +"#endif\n" +"#ifdef BIAS\n" +" FLOAT4 value0=vload4(0,input_C+offset.w+pos.x);\n" +" FLOAT4 value1=value0;\n" +" FLOAT4 value2=value0;\n" +" FLOAT4 value3=value0;\n" +"#else\n" +" FLOAT4 value0=(FLOAT4)0;\n" +" FLOAT4 value1=(FLOAT4)0;\n" +" FLOAT4 value2=(FLOAT4)0;\n" +" FLOAT4 value3=(FLOAT4)0;\n" +"#endif\n" +" const int l_pack=(l+3) >> 2;\n" +" for(int i=0; i= e) return;\n" +" vstore4(value1,0,output+output_offset+h);\n" +" if(pos.y+2 >= e) return;\n" +" vstore4(value2,0,output+output_offset+2*h);\n" +" if(pos.y+3 >= e) return;\n" +" vstore4(value3,0,output+output_offset+3*h);\n" +"#else\n" +" if(pos.x+3= e) return;\n" +" vstore4(value1,0,output+output_offset+h);\n" +" if(pos.y+2 >= e) return;\n" +" vstore4(value2,0,output+output_offset+2*h);\n" +" if(pos.y+3 >= e) return;\n" +" vstore4(value3,0,output+output_offset+3*h);\n" +" }else{\n" +"#if H_LEAVES == 1\n" +" output[output_offset]=value0.x;\n" +" if(pos.y+1 >= e) return;\n" +" output[output_offset+h]=value1.x;\n" +" if(pos.y+2 >= e) return;\n" +" output[output_offset+2*h]=value2.x;\n" +" if(pos.y+3 >= e) return;\n" +" output[output_offset+3*h]=value3.x;\n" +"#elif H_LEAVES == 2\n" +" vstore2((FLOAT2)value0.xy,0,output+output_offset);\n" +" if(pos.y+1 >= e) return;\n" +" vstore2((FLOAT2)value1.xy,0,output+output_offset+h);\n" +" if(pos.y+2 >= e) return;\n" +" vstore2((FLOAT2)value2.xy,0,output+output_offset+2*h);\n" +" if(pos.y+3 >= e) return;\n" +" vstore2((FLOAT2)value3.xy,0,output+output_offset+3*h);\n" +"#elif H_LEAVES == 3\n" +" vstore3((FLOAT3)value0.xyz,0,output+output_offset);\n" +" if(pos.y+1 >= e) return;\n" +" vstore3((FLOAT3)value1.xyz,0,output+output_offset+h);\n" +" if(pos.y+2 >= e) return;\n" +" vstore3((FLOAT3)value2.xyz,0,output+output_offset+2*h);\n" +" if(pos.y+3 >= e) return;\n" +" vstore3((FLOAT3)value3.xyz,0,output+output_offset+3*h);\n" +"#endif\n" +" }\n" +"#endif\n" +" }\n" +"}\n" +"__kernel void tile(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __read_only image2d_t input,\n" +" __global OUTPUT_TYPE* output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel){\n" +" int3 pos=(int3)(get_global_id(0),get_global_id(1),get_global_id(2));\n" +" if (pos.x= channel)return;\n" +" dst_ptr[c_dst_pitch]=value.y;\n" +" if(c+2 >= channel)return;\n" +" dst_ptr[2*c_dst_pitch]=value.z;\n" +" if(c+3 >= channel)return;\n" +" dst_ptr[3*c_dst_pitch]=value.w;\n" +" }\n" +"}\n" +"__kernel void pack(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __global INPUT_TYPE* input,\n" +" __write_only image2d_t output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel){\n" +" int3 pos=(int3)(get_global_id(0),get_global_id(1),get_global_id(2));\n" +" if (pos.x= 0) {\n" +" index.x=offset_dst[pos.z];\n" +" }\n" +" if (iters.y >= 0) {\n" +" index.y=offset_src[pos.z];\n" +" }\n" +" int2 offset=index*steps;\n" +" if(offset.x >= 0){\n" +" if(offset.y >= 0 && offset.y= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"#define ARGMAX_SELECT(A, B, C, D) "" if(A.x < B.x){ A.x = B.x; C.x = D; } "" if(A.y < B.y){ A.y = B.y; C.y = D; } "" if(A.z < B.z){ A.z = B.z; C.z = D; } "" if(A.w B.x){ A.x = B.x; C.x = D; } "" if(A.y > B.y){ A.y = B.y; C.y = D; } "" if(A.z > B.z){ A.z = B.z; C.z = D; } "" if(A.w>B.w){ A.w=B.w; C.w=D; } \n" +"__kernel void argmax_width_buf(GLOBAL_SIZE_3_DIMS\n" +" __global const FLOAT* input,\n" +" __global int* output,\n" +" __private const int inputWidth,\n" +" __private const int inputHeight,\n" +" __private const int inputChannel,\n" +" __private const int inputBatch,\n" +" __private const int inputChannelBlock,\n" +" __private const int oututWidth,\n" +" __private const int outputHeight,\n" +" __private const int outputChannel,\n" +" __private const int outputChannelBlock\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(x,height_idx,batch_channel_idx);\n" +" \n" +" const int batch_idx=batch_channel_idx/outputChannelBlock;\n" +" const int channel_idx=batch_channel_idx % outputChannelBlock;\n" +" \n" +" const int offset=((((batch_idx*inputChannelBlock)+channel_idx)*inputHeight+height_idx)*inputWidth+0)*4;\n" +" const int outputOffset=((((batch_idx*outputChannelBlock)+channel_idx)*outputHeight+height_idx)*oututWidth+0)*4;\n" +" int4 index=0;\n" +"#ifdef ARGMAX\n" +" FLOAT4 maxValue=(FLOAT4)-FLT_MAX;\n" +"#else\n" +" FLOAT4 maxValue=(FLOAT4)FLT_MAX;\n" +"#endif\n" +"#if ARGMAX_LOCAL_SIZE >= 4\n" +" int lid=get_local_id(0);\n" +" FLOAT4 local reduce[ARGMAX_LOCAL_SIZE];\n" +" int4 local index_reduce[ARGMAX_LOCAL_SIZE];\n" +" \n" +" for (int i=lid; i0; i /= 2){\n" +" if (lidreduce[lid+i].x){reduce[lid].x=reduce[lid+i].x; index_reduce[lid].x=index_reduce[lid+i].x;}\n" +" if(reduce[lid].y>reduce[lid+i].y){reduce[lid].y=reduce[lid+i].y; index_reduce[lid].y=index_reduce[lid+i].y;}\n" +" if(reduce[lid].z>reduce[lid+i].z){reduce[lid].z=reduce[lid+i].z; index_reduce[lid].z=index_reduce[lid+i].z;}\n" +" if(reduce[lid].w>reduce[lid+i].w){reduce[lid].w=reduce[lid+i].w; index_reduce[lid].w=index_reduce[lid+i].w;}\n" +"#endif\n" +" }\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" }\n" +" if(lid == 0){\n" +" vstore4(index_reduce[0],0,output+outputOffset);\n" +" }\n" +"#else\n" +" for(int i=0; i= 4\n" +" int lid=get_local_id(0);\n" +" FLOAT4 local reduce[ARGMAX_LOCAL_SIZE];\n" +" int4 local index_reduce[ARGMAX_LOCAL_SIZE];\n" +" \n" +" for (int i=lid; i0; i /= 2){\n" +" if (lidreduce[lid+i].x){reduce[lid].x=reduce[lid+i].x; index_reduce[lid].x=index_reduce[lid+i].x;}\n" +" if(reduce[lid].y>reduce[lid+i].y){reduce[lid].y=reduce[lid+i].y; index_reduce[lid].y=index_reduce[lid+i].y;}\n" +" if(reduce[lid].z>reduce[lid+i].z){reduce[lid].z=reduce[lid+i].z; index_reduce[lid].z=index_reduce[lid+i].z;}\n" +" if(reduce[lid].w>reduce[lid+i].w){reduce[lid].w=reduce[lid+i].w; index_reduce[lid].w=index_reduce[lid+i].w;}\n" +"#endif\n" +" }\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" }\n" +" if(lid == 0){\n" +" vstore4(index_reduce[0],0,output+outputOffset);\n" +" }\n" +"#else\n" +" for(int i=0; i= 4\n" +" int lid=get_local_id(0);\n" +" FLOAT local reduce[ARGMAX_LOCAL_SIZE];\n" +" int local index_reduce[ARGMAX_LOCAL_SIZE];\n" +" \n" +" for (int i=lid; ivaluePtr[j]){\n" +" index=i*4+j;\n" +" maxValue=valuePtr[j];\n" +" }\n" +"#endif\n" +" }\n" +" }\n" +" reduce[lid]=maxValue;\n" +" index_reduce[lid]=index;\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" for(int i=ARGMAX_LOCAL_SIZE/2; i>0; i /= 2){\n" +" if (lidreduce[lid+i]){reduce[lid]=reduce[lid+i]; index_reduce[lid]=index_reduce[lid+i];}\n" +"#endif\n" +" }\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" }\n" +" if(lid == 0){\n" +" maxValue=reduce[lid];\n" +" index=index_reduce[lid];\n" +" value=vload4((inputChannelBlock-1)*inputWidth*inputHeight,input+offset);\n" +" for(int j=0; jvaluePtr[j]){\n" +" index=(inputChannelBlock-1)*4+j;\n" +" maxValue=valuePtr[j];\n" +" }\n" +"#endif\n" +" }\n" +" output[outputOffset]=index;\n" +" }\n" +"#else\n" +" for(int i=0; ivaluePtr[j]){\n" +" index=i*4+j;\n" +" maxValue=valuePtr[j];\n" +" }\n" +"#endif\n" +" }\n" +" }\n" +" value=vload4((inputChannelBlock-1)*inputWidth*inputHeight,input+offset);\n" +" for(int j=0; jvaluePtr[j]){\n" +" index=(inputChannelBlock-1)*4+j;\n" +" maxValue=valuePtr[j];\n" +" }\n" +"#endif\n" +" }\n" +" output[outputOffset]=index;\n" +"#endif\n" +"}\n" +"__kernel void argmax_batch_buf(GLOBAL_SIZE_3_DIMS\n" +" __global const FLOAT* input,\n" +" __global int* output,\n" +" __private const int inputWidth,\n" +" __private const int inputHeight,\n" +" __private const int inputChannel,\n" +" __private const int inputBatch,\n" +" __private const int inputChannelBlock,\n" +" __private const int oututWidth,\n" +" __private const int outputHeight,\n" +" __private const int outputChannel,\n" +" __private const int outputChannelBlock\n" +" ) {\n" +" const int x=get_global_id(0);\n" +" const int wh=get_global_id(1);\n" +" const int channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(x,wh,channel_idx);\n" +" \n" +" const int width_idx=wh % oututWidth;\n" +" const int height_idx=wh/oututWidth;\n" +" const int offset=((((0*inputChannelBlock)+channel_idx)*inputHeight+height_idx)*inputWidth+width_idx)*4;\n" +" const int outputOffset=((((0*outputChannelBlock)+channel_idx)*outputHeight+height_idx)*oututWidth+width_idx)*4;\n" +" int4 index=0;\n" +" int batchOffset=inputChannelBlock*inputHeight*inputWidth;\n" +"#ifdef ARGMAX\n" +" FLOAT4 maxValue=(FLOAT4)-FLT_MAX;\n" +"#else\n" +" FLOAT4 maxValue=(FLOAT4)FLT_MAX;\n" +"#endif\n" +"#if ARGMAX_LOCAL_SIZE >= 4\n" +" int lid=get_local_id(0);\n" +" FLOAT4 local reduce[ARGMAX_LOCAL_SIZE];\n" +" int4 local index_reduce[ARGMAX_LOCAL_SIZE];\n" +" \n" +" for (int i=lid; i0; i /= 2){\n" +" if (lidreduce[lid+i].x){reduce[lid].x=reduce[lid+i].x; index_reduce[lid].x=index_reduce[lid+i].x;}\n" +" if(reduce[lid].y>reduce[lid+i].y){reduce[lid].y=reduce[lid+i].y; index_reduce[lid].y=index_reduce[lid+i].y;}\n" +" if(reduce[lid].z>reduce[lid+i].z){reduce[lid].z=reduce[lid+i].z; index_reduce[lid].z=index_reduce[lid+i].z;}\n" +" if(reduce[lid].w>reduce[lid+i].w){reduce[lid].w=reduce[lid+i].w; index_reduce[lid].w=index_reduce[lid+i].w;}\n" +"#endif\n" +" }\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" }\n" +" if(lid == 0){\n" +" vstore4(index_reduce[0],0,output+outputOffset);\n" +" }\n" +"#else\n" +" for(int i=0; i= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"// convert data from buffer(nhwc) to buffer(nc16hw16) float input\n" +"__kernel void nhwc_buffer_to_nc16hw16_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global const INPUT_TYPE *input_ptr,\n" +" __private const int height,\n" +" __private const int width,__private const int channels,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int input_pad_left,__private const int input_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_16_idx=(image_width_idx/width) << 4;\n" +" const int buffer_offset=((batch_idx*height+height_idx)*width+width_idx)*channels+channel_16_idx;\n" +" const int remain_channel=min(channels-channel_16_idx,16);\n" +" INPUT_TYPE16 values=0;\n" +" INPUT_TYPE* values_ptr=(INPUT_TYPE*)(&values);\n" +" __global const INPUT_TYPE *input_current_ptr=input_ptr+buffer_offset;\n" +" for(int i=0; i= src_bc_offset.x ? (INPUT_TYPE4)0 : vload4(0,input_ptr+src_buffer_offset+width_height_size4);\n" +" INPUT_TYPE4 values2=in_channel_block_idx+2 >= src_bc_offset.x ? (INPUT_TYPE4)0 : vload4(0,input_ptr+src_buffer_offset+width_height_size4*2);\n" +" INPUT_TYPE4 values3=in_channel_block_idx+3 >= src_bc_offset.x ? (INPUT_TYPE4)0 : vload4(0,input_ptr+src_buffer_offset+width_height_size4*3);\n" +" \n" +" vstore16(CONVERT_OUTPUT16((INPUT_TYPE16)(values0.s0123,values1.s0123,values2.s0123,values3.s0123)),0,output+dst_buffer_offset);\n" +" if(width_idx == 0){\n" +" int pad_offset=(((dst_bc_offset.x+dst_bc_offset.y)*output_shape.x+height_idx)*dst_width)*16;\n" +" for(int i=0; i= channelc4) return;\n" +" vstore4(CONVERT_OUTPUT4(values.s4567),0,output+dst_buffer_offset+width_height_size4);\n" +" if(out_channel_block_idx+2 >= channelc4) return;\n" +" vstore4(CONVERT_OUTPUT4(values.s89ab),0,output+dst_buffer_offset+2*width_height_size4);\n" +" if(out_channel_block_idx+3 >= channelc4) return;\n" +" vstore4(CONVERT_OUTPUT4(values.scdef),0,output+dst_buffer_offset+3*width_height_size4);\n" +"}\n" +; +#endif #endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* attention_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void matmul_qk_div_mask(GLOBAL_SIZE_3_DIMS\n" +" __global const FLOAT *input0,// query [1 query_seq_len/4 head_num head_dim 4]\n" +" __global const FLOAT *input1,// key [1 key_seq_len/4 head_num head_dim 4]\n" +" __global FLOAT *output,// prefill [1 head_num query_seq_len/4 key_seq_len 4] decode[1 head_num key_seq_len/4 4]\n" +" __global FLOAT *past_key,// [1 head_num max_length/4 head_dim 4]\n" +"#ifdef ADD_MASK\n" +" __global const FLOAT* mask,\n" +"#else\n" +" __global const int* mask,// [1 1 query_seq_len key_seq_len 4]\n" +"#endif\n" +" __private const float scale,\n" +" __private const int query_seq_len,\n" +" __private const int key_seq_len,\n" +" __private const int head_num,\n" +" __private const int kv_head_num,\n" +" __private const int head_dim) {\n" +" const int x=get_global_id(0); // query_seq_len/4 for prefill 1 for decode\n" +" const int y=get_global_id(1); // head_num\n" +" const int z=get_global_id(2); // key_seq_len/4\n" +" DEAL_NON_UNIFORM_DIM3(x,y,z);\n" +" \n" +" int yin=y/NUMHEAD_GROUP_SIZE;\n" +" const int offset=head_num*head_dim*4;\n" +" const int offset_head=y*head_dim*4;\n" +" __global const FLOAT *A_offset=input0+x*offset+offset_head;\n" +" __global FLOAT *Pastkey_offset=past_key+(z*kv_head_num+yin)*head_dim*4;\n" +" const int z4=z << 2;\n" +" float4 Vscale=(float4)scale;\n" +"#ifdef OPENCL_PREFILL_ATTENTION\n" +" __global const FLOAT *B_offset=input1+(z*kv_head_num+yin)*head_dim*4;\n" +" const int x4=x << 2;\n" +" const int query_seq_len4=(query_seq_len+3)/4;\n" +" const int output_offset=y*query_seq_len4*key_seq_len*4;\n" +" float4 out0=0;\n" +" float4 out1=0;\n" +" float4 out2=0;\n" +" float4 out3=0;\n" +" \n" +" const int head_dim4=(head_dim+3)/4;\n" +"#ifdef HEADDIM_LEAVE\n" +" for(int i=0; i= key_seq_len) return;\n" +" vstore4(CONVERT_FLOAT4(out1),0,output+output_offset+x*key_seq_len*4+(z4+1)*4);\n" +" if(z4+2 >= key_seq_len) return;\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+output_offset+x*key_seq_len*4+(z4+2)*4);\n" +" if(z4+3 >= key_seq_len) return;\n" +" vstore4(CONVERT_FLOAT4(out3),0,output+output_offset+x*key_seq_len*4+(z4+3)*4);\n" +"#else\n" +" __global const FLOAT *B_offset=input1+yin*head_dim*4;\n" +" const int key_seq_len4=(key_seq_len+3)/4;\n" +" float4 out=0;\n" +" const int head_dim4=(head_dim+3)/4;\n" +" \n" +"#ifdef HEADDIM_LEAVE\n" +" for(int i=0; i= head_dim) return;\n" +" vstore4(CONVERT_FLOAT4(out1),0,output+x*offset+(y*head_dim+z4+1)*4);\n" +" vstore4(CONVERT_FLOAT4(B.s4567),1,Pastvalue_offset+(value_seq_len4-1)*stride);\n" +" if(z4+2 >= head_dim) return;\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+x*offset+(y*head_dim+z4+2)*4);\n" +" vstore4(CONVERT_FLOAT4(B.s89ab),2,Pastvalue_offset+(value_seq_len4-1)*stride);\n" +" if(z4+3 >= head_dim) return;\n" +" vstore4(CONVERT_FLOAT4(out3),0,output+x*offset+(y*head_dim+z4+3)*4);\n" +" vstore4(CONVERT_FLOAT4(B.scdef),3,Pastvalue_offset+(value_seq_len4-1)*stride);\n" +"#else\n" +" COMPUTE_FLOAT16 B=CONVERT_COMPUTE_FLOAT16(vload16(0,B_offset+(value_seq_len4-1)*stride));\n" +" vstore16(CONVERT_FLOAT16(B),0,Pastvalue_offset+(value_seq_len4-1)*stride);\n" +" COMPUTE_FLOAT *B_ptr=(COMPUTE_FLOAT*)&B;\n" +" for(int i=(value_seq_len4-1)*4,j=0; i> 2)*stride+((value_seq_len-1) % 4);\n" +" \n" +"#ifdef HEADDIM_LEAVE\n" +" Pastvalue_offset[index]=B0;\n" +" output[(y*head_dim+z4)*4]=out.s0;\n" +" if(z4+1 >= head_dim) return;\n" +" Pastvalue_offset[index+4]=B1;\n" +" output[(y*head_dim+z4+1)*4]=out.s1;\n" +" if(z4+2 >= head_dim) return;\n" +" Pastvalue_offset[index+8]=B2;\n" +" output[(y*head_dim+z4+2)*4]=out.s2;\n" +" if(z4+3 >= head_dim) return;\n" +" Pastvalue_offset[index+12]=B3;\n" +" output[(y*head_dim+z4+3)*4]=out.s3;\n" +"#else\n" +" Pastvalue_offset[index]=B0;\n" +" Pastvalue_offset[index+4]=B1;\n" +" Pastvalue_offset[index+8]=B2;\n" +" Pastvalue_offset[index+12]=B3;\n" +" \n" +" output[(y*head_dim+z4)*4]=out.s0;\n" +" output[(y*head_dim+z4+1)*4]=out.s1;\n" +" output[(y*head_dim+z4+2)*4]=out.s2;\n" +" output[(y*head_dim+z4+3)*4]=out.s3;\n" +"#endif\n" +" \n" +"#endif\n" +"}\n" +; #endif #ifndef MNN_OPENCL_BUFFER_CLOSED -{ - "attention_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x71,0x6b,0x5f,0x64,0x69,0x76,0x5f,0x6d,0x61,0x73,0x6b,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x2f,0x2f,0x20,0x71,0x75,0x65,0x72,0x79,0x20,0x5b,0x31,0x20,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x2f,0x2f,0x20,0x6b,0x65,0x79,0x20,0x5b,0x31,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x70,0x72,0x65,0x66,0x69,0x6c,0x6c,0x20,0x5b,0x31,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x34,0x5d,0x20,0x20,0x20,0x64,0x65,0x63,0x6f,0x64,0x65,0x5b,0x31,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x70,0x61,0x73,0x74,0x5f,0x6b,0x65,0x79,0x2c,0x20,0x2f,0x2f,0x20,0x5b,0x31,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x34,0x5d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x41,0x44,0x44,0x5f,0x4d,0x41,0x53,0x4b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6d,0x61,0x73,0x6b,0x2c,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6d,0x61,0x73,0x6b,0x2c,0x20,0x2f,0x2f,0x20,0x5b,0x31,0x20,0x31,0x20,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x34,0x5d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x63,0x61,0x6c,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2f,0x20,0x34,0x20,0x66,0x6f,0x72,0x20,0x70,0x72,0x65,0x66,0x69,0x6c,0x6c,0x20,0x20,0x20,0x31,0x20,0x66,0x6f,0x72,0x20,0x64,0x65,0x63,0x6f,0x64,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x7a,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2f,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x79,0x2c,0x20,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x70,0x61,0x73,0x74,0x5f,0x6b,0x65,0x79,0x20,0x2b,0x20,0x7a,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x7a,0x34,0x20,0x3d,0x20,0x7a,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x56,0x73,0x63,0x61,0x6c,0x65,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x73,0x63,0x61,0x6c,0x65,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x52,0x45,0x46,0x49,0x4c,0x4c,0x5f,0x41,0x54,0x54,0x45,0x4e,0x54,0x49,0x4f,0x4e,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x7a,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x34,0x20,0x3d,0x20,0x78,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x3d,0x20,0x28,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x71,0x75,0x65,0x72,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x20,0x3d,0x20,0x28,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x48,0x45,0x41,0x44,0x44,0x49,0x4d,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x41,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x34,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x35,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x36,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x37,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x38,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x39,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x61,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x62,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x63,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x64,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x65,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x66,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x31,0x36,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x42,0x29,0x2c,0x20,0x69,0x2c,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x28,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x3b,0x20,0x69,0x20,0x3c,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x42,0x29,0x2c,0x20,0x69,0x2c,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x41,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x34,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x35,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x36,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x37,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x38,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x39,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x61,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x62,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x63,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x64,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x65,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x66,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x31,0x36,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x42,0x29,0x2c,0x20,0x69,0x2c,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x2a,0x3d,0x20,0x56,0x73,0x63,0x61,0x6c,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x2a,0x3d,0x20,0x56,0x73,0x63,0x61,0x6c,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x2a,0x3d,0x20,0x56,0x73,0x63,0x61,0x6c,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x2a,0x3d,0x20,0x56,0x73,0x63,0x61,0x6c,0x65,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x41,0x44,0x44,0x5f,0x4d,0x41,0x53,0x4b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x30,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x31,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x32,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x32,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x32,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x32,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x33,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x33,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x33,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x33,0x20,0x2b,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x30,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x32,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x30,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x30,0x2e,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x31,0x2e,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x32,0x2e,0x73,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x33,0x20,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x5b,0x28,0x28,0x78,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x3d,0x20,0x30,0x20,0x3f,0x20,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x20,0x3a,0x20,0x6f,0x75,0x74,0x33,0x2e,0x73,0x33,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x31,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x32,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x3d,0x20,0x28,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x20,0x3d,0x20,0x28,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x48,0x45,0x41,0x44,0x44,0x49,0x4d,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x41,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x30,0x2c,0x20,0x42,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x34,0x2c,0x20,0x42,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x38,0x2c,0x20,0x42,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x63,0x2c,0x20,0x42,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x28,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x3b,0x20,0x69,0x20,0x3c,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x30,0x2c,0x20,0x42,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x41,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x69,0x2c,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x30,0x2c,0x20,0x42,0x2e,0x73,0x30,0x31,0x32,0x33,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x34,0x2c,0x20,0x42,0x2e,0x73,0x34,0x35,0x36,0x37,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x38,0x2c,0x20,0x42,0x2e,0x73,0x38,0x39,0x61,0x62,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x41,0x2e,0x73,0x63,0x2c,0x20,0x42,0x2e,0x73,0x63,0x64,0x65,0x66,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x20,0x3d,0x3d,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2d,0x20,0x7a,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x3d,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x74,0x6d,0x70,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x41,0x20,0x3d,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x2a,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x42,0x20,0x3d,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x2a,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x6b,0x65,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x42,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x6d,0x70,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x6f,0x75,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x5f,0x70,0x74,0x72,0x5b,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5d,0x20,0x3d,0x20,0x74,0x6d,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x2a,0x3d,0x20,0x56,0x73,0x63,0x61,0x6c,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x6b,0x65,0x79,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x7a,0x34,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x71,0x6b,0x76,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x2f,0x2f,0x20,0x71,0x6b,0x20,0x70,0x72,0x65,0x66,0x69,0x6c,0x6c,0x20,0x5b,0x31,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x71,0x6b,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x34,0x5d,0x20,0x20,0x20,0x64,0x65,0x63,0x6f,0x64,0x65,0x5b,0x31,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x2f,0x2f,0x20,0x5b,0x31,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x2f,0x2f,0x20,0x5b,0x31,0x20,0x71,0x6b,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x2a,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x31,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x70,0x61,0x73,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x2f,0x2f,0x20,0x5b,0x31,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2f,0x34,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x71,0x6b,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x70,0x72,0x65,0x66,0x69,0x6c,0x6c,0x20,0x71,0x6b,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2f,0x20,0x34,0x20,0x20,0x20,0x64,0x65,0x63,0x6f,0x64,0x65,0x20,0x31,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x7a,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0x20,0x2f,0x2f,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x3c,0x3c,0x20,0x32,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x7a,0x34,0x20,0x3d,0x20,0x7a,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x79,0x2c,0x20,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x52,0x45,0x46,0x49,0x4c,0x4c,0x5f,0x41,0x54,0x54,0x45,0x4e,0x54,0x49,0x4f,0x4e,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x3d,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x71,0x6b,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x3d,0x20,0x28,0x71,0x6b,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x28,0x79,0x20,0x2a,0x20,0x71,0x6b,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2b,0x20,0x78,0x29,0x20,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x70,0x61,0x73,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x69,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x64,0x65,0x78,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x31,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x31,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x32,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x32,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x33,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x33,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x30,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x31,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x32,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x33,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x34,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x35,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x36,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x37,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x38,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x39,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x61,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x62,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x63,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x31,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x64,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x32,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x65,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x33,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x2e,0x73,0x66,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x31,0x36,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x42,0x29,0x2c,0x20,0x30,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x48,0x45,0x41,0x44,0x44,0x49,0x4d,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x42,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x2c,0x20,0x6a,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x20,0x2b,0x2b,0x6a,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x20,0x2b,0x20,0x34,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x20,0x2b,0x20,0x38,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x20,0x2b,0x20,0x31,0x32,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x30,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x42,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x31,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x42,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x2c,0x20,0x31,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x32,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x42,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x2c,0x20,0x32,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x6f,0x75,0x74,0x33,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x42,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x2c,0x20,0x33,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x31,0x36,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x42,0x29,0x2c,0x20,0x30,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x42,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x2c,0x20,0x6a,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x20,0x2b,0x2b,0x6a,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x30,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x30,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x31,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x20,0x2b,0x20,0x34,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x32,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x20,0x2b,0x20,0x38,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x33,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x41,0x30,0x2c,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x42,0x5f,0x70,0x74,0x72,0x5b,0x6a,0x20,0x2b,0x20,0x31,0x32,0x5d,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x31,0x36,0x28,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x29,0x28,0x6f,0x75,0x74,0x30,0x2c,0x20,0x6f,0x75,0x74,0x31,0x2c,0x20,0x6f,0x75,0x74,0x32,0x2c,0x20,0x6f,0x75,0x74,0x33,0x29,0x29,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x3d,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x6e,0x75,0x6d,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x20,0x3d,0x20,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2a,0x20,0x34,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x6f,0x6f,0x70,0x20,0x3d,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2b,0x20,0x32,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x34,0x20,0x2a,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x70,0x61,0x73,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x68,0x65,0x61,0x64,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6c,0x6f,0x6f,0x70,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x41,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x41,0x2c,0x20,0x42,0x2e,0x73,0x30,0x31,0x32,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x41,0x2c,0x20,0x42,0x2e,0x73,0x34,0x35,0x36,0x37,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x32,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x41,0x2c,0x20,0x42,0x2e,0x73,0x38,0x39,0x61,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x33,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x41,0x2c,0x20,0x42,0x2e,0x73,0x63,0x64,0x65,0x66,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x20,0x3d,0x20,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x2d,0x20,0x31,0x29,0x20,0x3c,0x20,0x30,0x20,0x3f,0x20,0x30,0x20,0x3a,0x20,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x2d,0x20,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x20,0x42,0x5f,0x56,0x65,0x63,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x31,0x36,0x28,0x76,0x6c,0x6f,0x61,0x64,0x31,0x36,0x28,0x30,0x2c,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x73,0x74,0x61,0x72,0x74,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x29,0x26,0x42,0x5f,0x56,0x65,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x73,0x74,0x61,0x72,0x74,0x20,0x2a,0x20,0x34,0x3b,0x20,0x69,0x20,0x3c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x41,0x20,0x3d,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x69,0x20,0x25,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x32,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x38,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x33,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x32,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x41,0x20,0x3d,0x20,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2d,0x20,0x31,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x42,0x30,0x20,0x3d,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x42,0x31,0x20,0x3d,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x34,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x42,0x32,0x20,0x3d,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x38,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x20,0x42,0x33,0x20,0x3d,0x20,0x42,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x31,0x32,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x32,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x73,0x33,0x20,0x2b,0x3d,0x20,0x41,0x20,0x2a,0x20,0x42,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2d,0x20,0x31,0x29,0x20,0x3e,0x3e,0x20,0x32,0x29,0x20,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x73,0x65,0x71,0x5f,0x6c,0x65,0x6e,0x20,0x2d,0x20,0x31,0x29,0x20,0x25,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x48,0x45,0x41,0x44,0x44,0x49,0x4d,0x5f,0x4c,0x45,0x41,0x56,0x45,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x20,0x3d,0x20,0x42,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x34,0x5d,0x20,0x3d,0x20,0x42,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x38,0x5d,0x20,0x3d,0x20,0x42,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x7a,0x34,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x31,0x32,0x5d,0x20,0x3d,0x20,0x42,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x33,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x20,0x3d,0x20,0x42,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x34,0x5d,0x20,0x3d,0x20,0x42,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x38,0x5d,0x20,0x3d,0x20,0x42,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x50,0x61,0x73,0x74,0x76,0x61,0x6c,0x75,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x20,0x2b,0x20,0x31,0x32,0x5d,0x20,0x3d,0x20,0x42,0x33,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x32,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x28,0x79,0x20,0x2a,0x20,0x68,0x65,0x61,0x64,0x5f,0x64,0x69,0x6d,0x20,0x2b,0x20,0x7a,0x34,0x20,0x2b,0x20,0x33,0x29,0x20,0x2a,0x20,0x34,0x5d,0x20,0x3d,0x20,0x6f,0x75,0x74,0x2e,0x73,0x33,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa, } - }, +const char* groupnorm_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__kernel void groupnorm_plain_buf(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +"#ifdef DOUBLE_INPUTS\n" +" __global const FLOAT*input0,\n" +" __global const FLOAT*input1,\n" +"#else\n" +" __global const FLOAT*input,\n" +"#endif\n" +" __global FLOAT*output,\n" +" __private const int area,\n" +" __private const int group,\n" +" __private const int inside,\n" +" __private const int outside,\n" +"#ifdef GAMMA_BETA\n" +" __global const FLOAT *gamma,\n" +" __global const FLOAT *beta,\n" +"#endif\n" +" __private float epsilon){\n" +" int3 pos=(int3)(get_global_id(0),get_global_id(1),get_global_id(2));\n" +" float local sum[LOCAL_SIZE];\n" +" if (pos.x> 2;\n" +" \n" +"#ifdef DOUBLE_INPUTS\n" +" // The product of W and H is a multiple of 4\n" +" #ifdef WH_4\n" +" float4 in_sum=0;\n" +" int index=lid;\n" +" for(; index0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid1) {\n" +" sum[lid]=sum[lid]+in_left.y;\n" +" }\n" +" if(inside_remain>2) {\n" +" sum[lid]=sum[lid]+in_left.z;\n" +" }\n" +" if(inside_remain>3) {\n" +" sum[lid]=sum[lid]+in_left.w;\n" +" }\n" +" }\n" +" \n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" for(int i=LOCAL_SIZE/2; i>0; i /= 2){\n" +" if (lid1) {\n" +" sum[lid]=sum[lid]+in_sum.y;\n" +" }\n" +" if(inside_remain>2) {\n" +" sum[lid]=sum[lid]+in_sum.z;\n" +" }\n" +" if(inside_remain>3) {\n" +" sum[lid]=sum[lid]+in_sum.w;\n" +" }\n" +" }\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" for(int i=LOCAL_SIZE/2; i>0; i /= 2){\n" +" if (lid= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"inline float4 gelu(float4 in){\n" +" float4 value=0.79788458f*(0.044715f*in*in*in+in);\n" +" float4 x2=value*value;\n" +" float4 dst=value>(float4)5.0f ? (float4)1.0f : (value <= -(float4)5.0f ? -(float4)1.0f :\n" +" (value*(135135.0f+x2*(17325.0f+x2*(378.0f+x2))))/(135135.0f+x2*(62370.0f+x2*(3150.0f+x2*28.0f))));\n" +" return (1.0f+dst)*in*0.5f;\n" +"}\n" +"__kernel void unary_buf_c4_c4(GLOBAL_SIZE_3_DIMS\n" +" __global const INPUT_TYPE *input,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel,\n" +" __private const int input_pad_left,__private const int input_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" const int channel_block_idx=get_global_id(0);\n" +" const int w=get_global_id(1);\n" +" const int hb=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(channel_block_idx,w,hb);\n" +" const int batch_idx=hb/height;\n" +" const int height_idx=hb % height;\n" +" const int channel4=(channel+3)/4;\n" +" const int offset=(((batch_idx*channel4+channel_block_idx)*height+height_idx)*width+w)*4;\n" +" float4 in=convert_float4(vload4(0,input+offset));\n" +" float4 out=OPERATOR;\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+offset);\n" +"}\n" +"__kernel void unary_buf_c4_c16(GLOBAL_SIZE_3_DIMS\n" +" __global const INPUT_TYPE *input,\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel,\n" +" __private const int input_pad_left,__private const int input_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right) {\n" +" const int channel_block_idx=get_global_id(0);\n" +" const int w=get_global_id(1);\n" +" const int hb=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(channel_block_idx,w,hb);\n" +" const int batch_idx=hb/height;\n" +" const int height_idx=hb % height;\n" +" const int dst_width=output_pad_left+width+output_pad_right;\n" +" const int channel4=(channel+3)/4;\n" +" const int channel16=(channel+15)/16;\n" +" const int channe_out_idx=channel_block_idx >> 2;\n" +" const int offset=(((batch_idx*channel4+channel_block_idx)*height+height_idx)*width+w)*4;\n" +" const int dst_offset=(((batch_idx*channel16+channe_out_idx)*height+height_idx)*dst_width+w+output_pad_left)*16+(channel_block_idx % 4)*4;\n" +" float4 in=convert_float4(vload4(0,input+offset));\n" +" float4 out=OPERATOR;\n" +" vstore4(CONVERT_OUTPUT4(out),0,output+dst_offset);\n" +" if(w == 0){\n" +" int pad_offset=(((batch_idx*channel16+channe_out_idx)*height+height_idx)*dst_width)*16+(channel_block_idx % 4)*4;\n" +" for(int i=0; iwidth) {\n" +" for (int i=0; iwidth ? (width % 4) : 4;\n" +" for (int i=0; i= global_size_dim0 || index1 >= global_size_dim1) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void gemm(__read_only image2d_t uInput,__read_only image2d_t uKernel,__write_only image2d_t uOutput,\n" +" __private const int width,__private const int height,__private const int multiLength,__private const int alpha2) {\n" +" \n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1)); \n" +" if (pos.x= 4){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" WI_F(uOutput,(int2)(out_x_idx+3,out_y_idx),o3);\n" +" }else if(remain == 3){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" }else if(remain == 2){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" }else if(remain == 1){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" }\n" +" }\n" +"}\n" +"__kernel void gemmWinogradW2(__read_only image2d_t uInput,__read_only image2d_t uKernel,__write_only image2d_t uOutput,\n" +" __private const int unitWidth,__private const int unitHeight,__private const int dstChannelC4,__private const int multiLength,__private const int alpha2) {\n" +" \n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" const int unitWidth8=(unitWidth+7)/8;\n" +" if (pos.x= 8){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" WI_F(uOutput,(int2)(out_x_idx+3,out_y_idx),o3);\n" +" WI_F(uOutput,(int2)(out_x_idx+4,out_y_idx),o4);\n" +" WI_F(uOutput,(int2)(out_x_idx+5,out_y_idx),o5);\n" +" WI_F(uOutput,(int2)(out_x_idx+6,out_y_idx),o6);\n" +" WI_F(uOutput,(int2)(out_x_idx+7,out_y_idx),o7);\n" +" }else if(remain == 7){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" WI_F(uOutput,(int2)(out_x_idx+3,out_y_idx),o3);\n" +" WI_F(uOutput,(int2)(out_x_idx+4,out_y_idx),o4);\n" +" WI_F(uOutput,(int2)(out_x_idx+5,out_y_idx),o5);\n" +" WI_F(uOutput,(int2)(out_x_idx+6,out_y_idx),o6);\n" +" }else if(remain == 6){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" WI_F(uOutput,(int2)(out_x_idx+3,out_y_idx),o3);\n" +" WI_F(uOutput,(int2)(out_x_idx+4,out_y_idx),o4);\n" +" WI_F(uOutput,(int2)(out_x_idx+5,out_y_idx),o5);\n" +" }else if(remain == 5){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" WI_F(uOutput,(int2)(out_x_idx+3,out_y_idx),o3);\n" +" WI_F(uOutput,(int2)(out_x_idx+4,out_y_idx),o4);\n" +" }else if(remain == 4){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" WI_F(uOutput,(int2)(out_x_idx+3,out_y_idx),o3);\n" +" }else if(remain == 3){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" WI_F(uOutput,(int2)(out_x_idx+2,out_y_idx),o2);\n" +" }else if(remain == 2){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" WI_F(uOutput,(int2)(out_x_idx+1,out_y_idx),o1);\n" +" }else if(remain == 1){\n" +" WI_F(uOutput,(int2)(out_x_idx,out_y_idx),o0);\n" +" }\n" +" }\n" +"}\n" +"#ifdef INPUT_CHANNEL_LEAVE\n" +" #define PADZEROSVEC(k, channel, data0, data1, data2, data3) "" data0 = (k << 2) < channel ? data0 : 0; "" data1 = (k << 2) + 1 < channel ? data1 : 0; "" data2 = (k << 2) + 2 < channel ? data2 : 0; "" data3=(k << 2)+3> 4)-8;\n" +" charWeights.s1=(charWeightsInt4.s0 & 15)-8;\n" +" charWeights.s2=(charWeightsInt4.s1 >> 4)-8;\n" +" charWeights.s3=(charWeightsInt4.s1 & 15)-8;\n" +" charWeights.s4=(charWeightsInt4.s2 >> 4)-8;\n" +" charWeights.s5=(charWeightsInt4.s2 & 15)-8;\n" +" charWeights.s6=(charWeightsInt4.s3 >> 4)-8;\n" +" charWeights.s7=(charWeightsInt4.s3 & 15)-8;\n" +" charWeights.s8=(charWeightsInt4.s4 >> 4)-8;\n" +" charWeights.s9=(charWeightsInt4.s4 & 15)-8;\n" +" charWeights.sa=(charWeightsInt4.s5 >> 4)-8;\n" +" charWeights.sb=(charWeightsInt4.s5 & 15)-8;\n" +" charWeights.sc=(charWeightsInt4.s6 >> 4)-8;\n" +" charWeights.sd=(charWeightsInt4.s6 & 15)-8;\n" +" charWeights.se=(charWeightsInt4.s7 >> 4)-8;\n" +" charWeights.sf=(charWeightsInt4.s7 & 15)-8;\n" +" FLOAT16 weights=CONVERT_FLOAT16(charWeights)*scale+offset;\n" +" \n" +"#else\n" +" FLOAT16 weights=vload16(0,weight+weight_offset+k*weight_oc_offset);\n" +"#endif\n" +" PADZEROSVEC(k,srcChannel,weights.s0123,weights.s4567,weights.s89ab,weights.scdef);\n" +" \n" +" out=mad((FLOAT4)in.x,(FLOAT4)weights.s0123,out);\n" +" out=mad((FLOAT4)in.y,(FLOAT4)weights.s4567,out);\n" +" out=mad((FLOAT4)in.z,(FLOAT4)weights.s89ab,out);\n" +" out=mad((FLOAT4)in.w,(FLOAT4)weights.scdef,out);\n" +" }\n" +" \n" +"#ifdef RELU\n" +" out=fmax(out,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out=clamp(out,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" WI_F(output,(int2)(pos.x,pos.y),out);\n" +"}\n" +"__kernel void gemm_conv_b2(GLOBAL_SIZE_DIM2\n" +" __read_only image2d_t input,\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" __global const char *weight,\n" +" __global const float *dequantScaleOffset,\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" __global const uchar *weight,\n" +" __global const float *dequantScaleOffset,\n" +"#else\n" +" __global const FLOAT *weight,\n" +"#endif\n" +" __read_only image2d_t bias,\n" +" __write_only image2d_t output,\n" +" __private const int dstChannelC4,\n" +" __private const int srcChannelC4,\n" +" __private const int batch\n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8) || (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" ,__private const int blockDim\n" +" ,__private const int srcChannel\n" +"#endif\n" +") {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1)); //cout/4,b\n" +" UNIFORM_BOUNDRY_CHECK(pos.x,pos.y);\n" +" int pos_x=pos.x << 2;\n" +" int pos_y=pos.y << 1;\n" +" FLOAT4 bias0=RI_F(bias,SAMPLER,(int2)(pos.x,0));\n" +" FLOAT4 out0=bias0,out1=bias0;\n" +" \n" +"#if (defined USE_LOW_BIT_WEIGHT_INT8)\n" +" int weight_offset=pos.x*16;\n" +" int weight_oc_offset=dstChannelC4*16;\n" +"#elif (defined USE_LOW_BIT_WEIGHT_INT4)\n" +" int weight_offset=pos.x*8;\n" +" int weight_oc_offset=dstChannelC4*8;\n" +"#else\n" +" int weight_offset=pos.x*16;\n" +" int weight_oc_offset=dstChannelC4*16;\n" +"#endif\n" +" for (int k=0; k> 4)-8;\n" +" charWeights.s1=(charWeightsInt4.s0 & 15)-8;\n" +" charWeights.s2=(charWeightsInt4.s1 >> 4)-8;\n" +" charWeights.s3=(charWeightsInt4.s1 & 15)-8;\n" +" charWeights.s4=(charWeightsInt4.s2 >> 4)-8;\n" +" charWeights.s5=(charWeightsInt4.s2 & 15)-8;\n" +" charWeights.s6=(charWeightsInt4.s3 >> 4)-8;\n" +" charWeights.s7=(charWeightsInt4.s3 & 15)-8;\n" +" charWeights.s8=(charWeightsInt4.s4 >> 4)-8;\n" +" charWeights.s9=(charWeightsInt4.s4 & 15)-8;\n" +" charWeights.sa=(charWeightsInt4.s5 >> 4)-8;\n" +" charWeights.sb=(charWeightsInt4.s5 & 15)-8;\n" +" charWeights.sc=(charWeightsInt4.s6 >> 4)-8;\n" +" charWeights.sd=(charWeightsInt4.s6 & 15)-8;\n" +" charWeights.se=(charWeightsInt4.s7 >> 4)-8;\n" +" charWeights.sf=(charWeightsInt4.s7 & 15)-8;\n" +" FLOAT16 weights=CONVERT_FLOAT16(charWeights)*scale+offset;\n" +"#else\n" +" FLOAT16 weights=vload16(0,weight+weight_offset+k*weight_oc_offset);\n" +"#endif\n" +" PADZEROSVEC(k,srcChannel,weights.s0123,weights.s4567,weights.s89ab,weights.scdef);\n" +" \n" +" out0=mad((FLOAT4)in0.x,(FLOAT4)weights.s0123,out0);\n" +" out0=mad((FLOAT4)in0.y,(FLOAT4)weights.s4567,out0);\n" +" out0=mad((FLOAT4)in0.z,(FLOAT4)weights.s89ab,out0);\n" +" out0=mad((FLOAT4)in0.w,(FLOAT4)weights.scdef,out0);\n" +" \n" +" out1=mad((FLOAT4)in1.x,(FLOAT4)weights.s0123,out1);\n" +" out1=mad((FLOAT4)in1.y,(FLOAT4)weights.s4567,out1);\n" +" out1=mad((FLOAT4)in1.z,(FLOAT4)weights.s89ab,out1);\n" +" out1=mad((FLOAT4)in1.w,(FLOAT4)weights.scdef,out1);\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(FLOAT4)0);\n" +" out1=fmax(out1,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(FLOAT4)0,(FLOAT4)6);\n" +" out1=clamp(out1,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" WI_F(output,(int2)(pos.x,pos_y),out0);\n" +" if(pos_y+1= input_shape.y)); "" in##i=read_imagef(input,SAMPLER,(int2)(in_width_value##i,in_hb_value));\n" +"#define CALCULATE_OUTPUT(i) "" out##i = mad(in##i.x, weights0, out##i); "" out##i = mad(in##i.y, weights1, out##i); "" out##i = mad(in##i.z, weights2, out##i); "" out##i=mad(in##i.w,weights3,out##i);\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void depthwise_deconv2d(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,\n" +" __read_only image2d_t weights,\n" +" #ifndef NO_BIAS\n" +" __read_only image2d_t bias,\n" +" #endif\n" +" __write_only image2d_t output,\n" +" __private const int2 input_shape,\n" +" __private const int2 output_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 align_shape,\n" +" __private const int2 padding_shape,\n" +" __private const int2 kernel_shape,\n" +" __private const int kernel_size,__private const int out_channel_blocks) {\n" +" const int out_channel_blocks_idx=get_global_id(0);\n" +" const int out_width_idx=get_global_id(1);\n" +" const int out_batch_height_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(out_channel_blocks_idx,out_width_idx,out_batch_height_idx);\n" +" #ifndef NO_BIAS\n" +" float4 out0=read_imagef(bias,SAMPLER,(int2)(out_channel_blocks_idx,0));\n" +" #else\n" +" float4 out0=(float4)(0.0);\n" +" #endif\n" +" const int out_batch_idx=out_batch_height_idx/output_shape.x;\n" +" const int out_height_idx=out_batch_height_idx % output_shape.x;\n" +" int kernel_start_x=(out_width_idx+align_shape.y)/stride_shape.y;\n" +" int kernel_start_y=(out_height_idx+align_shape.x)/stride_shape.x;\n" +" int deal_kernel_width=kernel_shape.y-mad24(kernel_start_x,stride_shape.y,padding_shape.y)+out_width_idx-1;\n" +" int deal_kernel_height=kernel_shape.x-mad24(kernel_start_y,stride_shape.x,padding_shape.x)+out_height_idx-1;\n" +" int kernel_image_x;\n" +" float4 in0;\n" +" float4 weight;\n" +" int in_width0;\n" +" int in_idx,in_idy;\n" +" for (int k_y=deal_kernel_height,idx_h=kernel_start_y; k_y >= 0; k_y -= stride_shape.x,idx_h++) {\n" +" in_idy=mad24(out_batch_idx,input_shape.x,idx_h);\n" +" int in_hb_value=select(in_idy,-1,idx_h<0 || idx_h >= input_shape.x);\n" +" for (int k_x=deal_kernel_width,in_width_idx=kernel_start_x; k_x >= 0; k_x -= stride_shape.y,in_width_idx++) {\n" +" in_width0=in_width_idx;\n" +" in_idx=mul24(out_channel_blocks_idx,input_shape.y);\n" +" READ_INPUT_IMAGE(0,0);\n" +" kernel_image_x=mad24(k_y,kernel_shape.y,k_x);\n" +" weight=read_imagef(weights,SAMPLER,(int2)(kernel_image_x,out_channel_blocks_idx));\n" +" out0=mad(in0,weight,out0);\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(float4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(float4)0,(float4)6);\n" +"#endif\n" +" const int output_image_x=mad24(out_channel_blocks_idx,output_shape.y,out_width_idx);\n" +" write_imagef(output,(int2)(output_image_x,out_batch_height_idx),out0);\n" +" }\n" +"}\n" +; +const char* range = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void range(GLOBAL_SIZE_3_DIMS\n" +" __read_only image2d_t input0,\n" +" __read_only image2d_t input2,\n" +" __write_only image2d_t output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel,\n" +" __private const int channelBlock\n" +" ) {\n" +" const int width_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int batch_idx=batch_channel_idx/channelBlock;\n" +" const int channel_idx=batch_channel_idx % channelBlock;\n" +" \n" +" const int bh=batch_idx*height+height_idx;\n" +" const int cw=channel_idx*width+width_idx;\n" +" const int channel4=channel_idx << 2;\n" +" int index=(((batch_idx*channel)+channel4)*height+height_idx)*width+width_idx;\n" +" int size=height*width;\n" +" int4 index4=(int4)(index,index+size,index+size*2,index+size*3);\n" +" INPUT_TYPE_I start=RI_DATA(input0,SAMPLER,(int2)(0,0)).x;\n" +" INPUT_TYPE_I step=RI_DATA(input2,SAMPLER,(int2)(0,0)).x;\n" +" OUTPUT_TYPE_I4 value=(OUTPUT_TYPE_I4)start+CONVERT_OUTPUT_I4(index4)*(OUTPUT_TYPE_I4)step;\n" +" WI_DATA(output,(int2)(cw,bh),value);\n" +"}\n" +; +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* scale_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__kernel void scale_buf(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT* input,\n" +" __global const FLOAT* scale,\n" +"#ifdef BIAS\n" +" __global const FLOAT* bias,\n" +"#endif\n" +" __global FLOAT* output,\n" +" __private const int4 shape) {//N,H,W,C4\n" +" const int out_w_c_idx=get_global_id(0);\n" +" const int out_h_b_idx=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(out_w_c_idx,out_h_b_idx);\n" +" const int out_b_idx=out_h_b_idx/shape.y;\n" +" const int out_h_idx=out_h_b_idx % shape.y;\n" +" const int out_c_idx=out_w_c_idx/shape.z;\n" +" const int out_w_idx=out_w_c_idx % shape.z;\n" +" \n" +" const int offset=(((out_b_idx*shape.w+out_c_idx)*shape.y+out_h_idx)*shape.z+out_w_idx)*4;\n" +" COMPUTE_FLOAT4 in_value=CONVERT_COMPUTE_FLOAT4(vload4(0,input+offset));\n" +" COMPUTE_FLOAT4 scale_value=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,scale));\n" +"#ifdef BIAS\n" +" COMPUTE_FLOAT4 bias_value=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out_value=in_value*scale_value+bias_value;\n" +"#else\n" +" COMPUTE_FLOAT4 out_value=in_value*scale_value;\n" +"#endif\n" +" vstore4(CONVERT_FLOAT4(out_value),0,output+offset);\n" +"}\n" +; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* matmul_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) ""if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { ""return; ""}\n" +"__kernel void matmul_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* input_a,\n" +" __global const FLOAT* input_b,\n" +" #ifdef BIAS\n" +" __global const FLOAT* input_c,\n" +" #endif\n" +" __global FLOAT* output_c,\n" +" __private const int channels,\n" +" __private const int channel_blocks,\n" +" __private const int width_blocks,\n" +" __private const int width) {\n" +" const int width_blocks_idx=get_global_id(0);// output W\n" +" const int height_idx=get_global_id(1);// output H\n" +" DEAL_NON_UNIFORM_DIM2(width_blocks_idx,height_idx);\n" +" COMPUTE_FLOAT4 a;\n" +" COMPUTE_FLOAT4 b0=0,b1=0,b2=0,b3=0;\n" +" COMPUTE_FLOAT4 v_zero=(COMPUTE_FLOAT4)((COMPUTE_FLOAT)0.0);\n" +" #ifdef BIAS\n" +" COMPUTE_FLOAT4 temp=CONVERT_COMPUTE_FLOAT4(vload4(width_blocks_idx,input_c));\n" +" COMPUTE_FLOAT result0=temp.x;\n" +" COMPUTE_FLOAT result1=temp.y;\n" +" COMPUTE_FLOAT result2=temp.z;\n" +" COMPUTE_FLOAT result3=temp.w;\n" +" #else\n" +" COMPUTE_FLOAT result0=0;\n" +" COMPUTE_FLOAT result1=0;\n" +" COMPUTE_FLOAT result2=0;\n" +" COMPUTE_FLOAT result3=0;\n" +" #endif\n" +" const int remain=channel_blocks*4-channels;\n" +" for (short pos=0; pos= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+width_blocks,input_b));\n" +" b2=(remain >= 2) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+width_blocks*2,input_b));\n" +" b3=(remain >= 1) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+width_blocks*3,input_b));\n" +" if (remain == 3) {\n" +" a.y=0;\n" +" a.z=0;\n" +" a.w=0;\n" +" } else if (remain == 2) {\n" +" a.z=0;\n" +" a.w=0;\n" +" } else if (remain == 1) {\n" +" a.w=0;;\n" +" }\n" +" COMPUTE_FLOAT4 btmp0=(COMPUTE_FLOAT4)(b0.s0,b1.s0,b2.s0,b3.s0);\n" +" COMPUTE_FLOAT4 btmp1=(COMPUTE_FLOAT4)(b0.s1,b1.s1,b2.s1,b3.s1);\n" +" COMPUTE_FLOAT4 btmp2=(COMPUTE_FLOAT4)(b0.s2,b1.s2,b2.s2,b3.s2);\n" +" COMPUTE_FLOAT4 btmp3=(COMPUTE_FLOAT4)(b0.s3,b1.s3,b2.s3,b3.s3);\n" +" result0 += dot(a,btmp0);\n" +" result1 += dot(a,btmp1);\n" +" result2 += dot(a,btmp2);\n" +" result3 += dot(a,btmp3);\n" +" }\n" +" const int out_offset=height_idx*width_blocks+width_blocks_idx;\n" +" vstore4(CONVERT_FLOAT4((COMPUTE_FLOAT4)(result0,result1,result2,result3)),out_offset,output_c);\n" +"}\n" +"__kernel void matmul_transB_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* input_a,\n" +" __global const FLOAT* input_b,\n" +" #ifdef BIAS\n" +" __global const FLOAT* input_c,\n" +" #endif\n" +" __global FLOAT* output_c,\n" +" __private const int channels,\n" +" __private const int channel_blocks,\n" +" __private const int width_blocks,\n" +" __private const int width) {\n" +" const int width_blocks_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(width_blocks_idx,height_idx);\n" +" COMPUTE_FLOAT4 a;\n" +" COMPUTE_FLOAT4 b0=0,b1=0,b2=0,b3=0;\n" +" COMPUTE_FLOAT4 v_zero=(COMPUTE_FLOAT4)((COMPUTE_FLOAT)0.0);\n" +" #ifdef BIAS\n" +" COMPUTE_FLOAT4 temp=CONVERT_COMPUTE_FLOAT4(vload4(width_blocks_idx,input_c));\n" +" COMPUTE_FLOAT result0=temp.x;\n" +" COMPUTE_FLOAT result1=temp.y;\n" +" COMPUTE_FLOAT result2=temp.z;\n" +" COMPUTE_FLOAT result3=temp.w;\n" +" #else\n" +" COMPUTE_FLOAT result0=0;\n" +" COMPUTE_FLOAT result1=0;\n" +" COMPUTE_FLOAT result2=0;\n" +" COMPUTE_FLOAT result3=0;\n" +" #endif\n" +" const int remaina=channel_blocks*4-channels;\n" +" const int remainb=(width_blocks_idx+1)*4-width;\n" +" for (short pos=0; pos= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks,input_b));\n" +" b2=(remainb >= 2) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*2,input_b));\n" +" b3=(remainb >= 1) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*3,input_b));\n" +" result0 += dot(a,b0);\n" +" result1 += dot(a,b1);\n" +" result2 += dot(a,b2);\n" +" result3 += dot(a,b3);\n" +" }\n" +" \n" +" {\n" +" const int inpa_offset=height_idx*channel_blocks+channel_blocks-1;\n" +" a=CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset,input_a));\n" +" const int inpb_offset=(width_blocks_idx*4)*channel_blocks+channel_blocks-1;\n" +" b0=CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset,input_b));\n" +" b1=(remainb >= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks,input_b));\n" +" b2=(remainb >= 2) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*2,input_b));\n" +" b3=(remainb >= 1) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*3,input_b));\n" +" if (remaina == 3) {\n" +" a.y=0;\n" +" a.z=0;\n" +" a.w=0;\n" +" } else if (remaina == 2) {\n" +" a.z=0;\n" +" a.w=0;\n" +" } else if (remaina == 1) {\n" +" a.w=0;\n" +" }\n" +" result0 += dot(a,b0);\n" +" result1 += dot(a,b1);\n" +" result2 += dot(a,b2);\n" +" result3 += dot(a,b3);\n" +" }\n" +" const int out_offset=height_idx*width_blocks+width_blocks_idx;\n" +" vstore4(CONVERT_FLOAT4((COMPUTE_FLOAT4)(result0,result1,result2,result3)),out_offset,output_c);\n" +"}\n" +"__kernel void matmul_transA_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* input_a,\n" +" __global const FLOAT* input_b,\n" +" #ifdef BIAS\n" +" __global const FLOAT* input_c,\n" +" #endif\n" +" __global FLOAT* output_c,\n" +" __private const int channels,\n" +" __private const int channel_blocks,\n" +" __private const int height,\n" +" __private const int height_blocks,\n" +" __private const int width_blocks,\n" +" __private const int width) {\n" +" const int width_blocks_idx=get_global_id(0);\n" +" const int height_blocks_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(width_blocks_idx,height_blocks_idx);\n" +" COMPUTE_FLOAT4 v_zero=(COMPUTE_FLOAT4)((COMPUTE_FLOAT)0.0);\n" +" #ifdef BIAS\n" +" COMPUTE_FLOAT4 result0=CONVERT_COMPUTE_FLOAT4(vload4(width_blocks_idx,input_c));\n" +" COMPUTE_FLOAT4 result1=result0;\n" +" COMPUTE_FLOAT4 result2=result0;\n" +" COMPUTE_FLOAT4 result3=result0;\n" +" #else\n" +" COMPUTE_FLOAT4 result0=0;\n" +" COMPUTE_FLOAT4 result1=0;\n" +" COMPUTE_FLOAT4 result2=0;\n" +" COMPUTE_FLOAT4 result3=0;\n" +" #endif\n" +" \n" +" const int remain=channel_blocks*4-channels;\n" +" for (short pos=0; pos= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset+height_blocks,input_a)));\n" +" COMPUTE_FLOAT4 a2=((remain >= 2) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset+height_blocks*2,input_a)));\n" +" COMPUTE_FLOAT4 a3=((remain >= 1) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset+height_blocks*3,input_a)));\n" +" const int inpb_offset=(4*(channel_blocks-1))*width_blocks+width_blocks_idx;\n" +" COMPUTE_FLOAT4 b0=CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset,input_b));\n" +" COMPUTE_FLOAT4 b1=((remain >= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+width_blocks,input_b)));\n" +" COMPUTE_FLOAT4 b2=((remain >= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+width_blocks*2,input_b)));\n" +" COMPUTE_FLOAT4 b3=((remain >= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+width_blocks*3,input_b)));\n" +" COMPUTE_FLOAT4 a0_trans=(COMPUTE_FLOAT4)(a0.x,a1.x,a2.x,a3.x);\n" +" COMPUTE_FLOAT4 a1_trans=(COMPUTE_FLOAT4)(a0.y,a1.y,a2.y,a3.y);\n" +" COMPUTE_FLOAT4 a2_trans=(COMPUTE_FLOAT4)(a0.z,a1.z,a2.z,a3.z);\n" +" COMPUTE_FLOAT4 a3_trans=(COMPUTE_FLOAT4)(a0.w,a1.w,a2.w,a3.w);\n" +" \n" +" COMPUTE_FLOAT4 b0_trans=(COMPUTE_FLOAT4)(b0.x,b1.x,b2.x,b3.x);\n" +" COMPUTE_FLOAT4 b1_trans=(COMPUTE_FLOAT4)(b0.y,b1.y,b2.y,b3.y);\n" +" COMPUTE_FLOAT4 b2_trans=(COMPUTE_FLOAT4)(b0.z,b1.z,b2.z,b3.z);\n" +" COMPUTE_FLOAT4 b3_trans=(COMPUTE_FLOAT4)(b0.w,b1.w,b2.w,b3.w);\n" +" //matmul\n" +" result0.x += dot(a0_trans,b0_trans);\n" +" result0.y += dot(a0_trans,b1_trans);\n" +" result0.z += dot(a0_trans,b2_trans);\n" +" result0.w += dot(a0_trans,b3_trans);\n" +" \n" +" result1.x += dot(a1_trans,b0_trans);\n" +" result1.y += dot(a1_trans,b1_trans);\n" +" result1.z += dot(a1_trans,b2_trans);\n" +" result1.w += dot(a1_trans,b3_trans);\n" +" \n" +" result2.x += dot(a2_trans,b0_trans);\n" +" result2.y += dot(a2_trans,b1_trans);\n" +" result2.z += dot(a2_trans,b2_trans);\n" +" result2.w += dot(a2_trans,b3_trans);\n" +" \n" +" result3.x += dot(a3_trans,b0_trans);\n" +" result3.y += dot(a3_trans,b1_trans);\n" +" result3.z += dot(a3_trans,b2_trans);\n" +" result3.w += dot(a3_trans,b3_trans);\n" +" }\n" +" \n" +" const int out_offset=(4*height_blocks_idx)*width_blocks+width_blocks_idx;\n" +" vstore4(CONVERT_FLOAT4(result0),out_offset,output_c);\n" +" if(4*height_blocks_idx+1 >= height) return;\n" +" vstore4(CONVERT_FLOAT4(result1),out_offset+width_blocks,output_c);\n" +" if(4*height_blocks_idx+2 >= height) return;\n" +" vstore4(CONVERT_FLOAT4(result2),out_offset+width_blocks*2,output_c);\n" +" if(4*height_blocks_idx+3 >= height) return;\n" +" vstore4(CONVERT_FLOAT4(result3),out_offset+width_blocks*3,output_c);\n" +"}\n" +"__kernel void matmul_transA_transB_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* input_a,\n" +" __global const FLOAT* input_b,\n" +" #ifdef BIAS\n" +" __global const FLOAT* input_c,\n" +" #endif\n" +" __global FLOAT* output_c,\n" +" __private const int channels,\n" +" __private const int channel_blocks,\n" +" __private const int height,\n" +" __private const int height_blocks,\n" +" __private const int width_blocks,\n" +" __private const int width) {\n" +" const int width_blocks_idx=get_global_id(0);\n" +" const int height_blocks_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(width_blocks_idx,height_blocks_idx);\n" +" COMPUTE_FLOAT4 v_zero=(COMPUTE_FLOAT4)((COMPUTE_FLOAT)0.0);\n" +" #ifdef BIAS\n" +" COMPUTE_FLOAT4 result0=CONVERT_COMPUTE_FLOAT4(vload4(width_blocks_idx,input_c));\n" +" COMPUTE_FLOAT4 result1=result0;\n" +" COMPUTE_FLOAT4 result2=result0;\n" +" COMPUTE_FLOAT4 result3=result0;\n" +" #else\n" +" COMPUTE_FLOAT4 result0=0;\n" +" COMPUTE_FLOAT4 result1=0;\n" +" COMPUTE_FLOAT4 result2=0;\n" +" COMPUTE_FLOAT4 result3=0;\n" +" #endif\n" +" \n" +" const int remaina=channel_blocks*4-channels;\n" +" const int remainb=(width_blocks_idx+1)*4-width;\n" +" for (short pos=0; pos= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks,input_b)));\n" +" COMPUTE_FLOAT4 b2=((remainb >= 2) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*2,input_b)));\n" +" COMPUTE_FLOAT4 b3=((remainb >= 1) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*3,input_b)));\n" +" COMPUTE_FLOAT4 a0_trans=(COMPUTE_FLOAT4)(a0.x,a1.x,a2.x,a3.x);\n" +" COMPUTE_FLOAT4 a1_trans=(COMPUTE_FLOAT4)(a0.y,a1.y,a2.y,a3.y);\n" +" COMPUTE_FLOAT4 a2_trans=(COMPUTE_FLOAT4)(a0.z,a1.z,a2.z,a3.z);\n" +" COMPUTE_FLOAT4 a3_trans=(COMPUTE_FLOAT4)(a0.w,a1.w,a2.w,a3.w);\n" +" //matmul\n" +" result0.x += dot(a0_trans,b0);\n" +" result0.y += dot(a0_trans,b1);\n" +" result0.z += dot(a0_trans,b2);\n" +" result0.w += dot(a0_trans,b3);\n" +" \n" +" result1.x += dot(a1_trans,b0);\n" +" result1.y += dot(a1_trans,b1);\n" +" result1.z += dot(a1_trans,b2);\n" +" result1.w += dot(a1_trans,b3);\n" +" \n" +" result2.x += dot(a2_trans,b0);\n" +" result2.y += dot(a2_trans,b1);\n" +" result2.z += dot(a2_trans,b2);\n" +" result2.w += dot(a2_trans,b3);\n" +" \n" +" result3.x += dot(a3_trans,b0);\n" +" result3.y += dot(a3_trans,b1);\n" +" result3.z += dot(a3_trans,b2);\n" +" result3.w += dot(a3_trans,b3);\n" +" }\n" +" \n" +" {\n" +" const int inpa_offset=(4*(channel_blocks-1))*height_blocks+height_blocks_idx;\n" +" COMPUTE_FLOAT4 a0=CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset,input_a));\n" +" COMPUTE_FLOAT4 a1=((remaina >= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset+height_blocks,input_a)));\n" +" COMPUTE_FLOAT4 a2=((remaina >= 2) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset+height_blocks*2,input_a)));\n" +" COMPUTE_FLOAT4 a3=((remaina >= 1) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpa_offset+height_blocks*3,input_a)));\n" +" const int inpb_offset=(4*width_blocks_idx)*channel_blocks+channel_blocks-1;\n" +" COMPUTE_FLOAT4 b0=CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset,input_b));\n" +" COMPUTE_FLOAT4 b1=((remainb >= 3) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks,input_b)));\n" +" COMPUTE_FLOAT4 b2=((remainb >= 2) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*2,input_b)));\n" +" COMPUTE_FLOAT4 b3=((remainb >= 1) ? v_zero : CONVERT_COMPUTE_FLOAT4(vload4(inpb_offset+channel_blocks*3,input_b)));\n" +" COMPUTE_FLOAT4 a0_trans=(COMPUTE_FLOAT4)(a0.x,a1.x,a2.x,a3.x);\n" +" COMPUTE_FLOAT4 a1_trans=(COMPUTE_FLOAT4)(a0.y,a1.y,a2.y,a3.y);\n" +" COMPUTE_FLOAT4 a2_trans=(COMPUTE_FLOAT4)(a0.z,a1.z,a2.z,a3.z);\n" +" COMPUTE_FLOAT4 a3_trans=(COMPUTE_FLOAT4)(a0.w,a1.w,a2.w,a3.w);\n" +" //matmul\n" +" result0.x += dot(a0_trans,b0);\n" +" result0.y += dot(a0_trans,b1);\n" +" result0.z += dot(a0_trans,b2);\n" +" result0.w += dot(a0_trans,b3);\n" +" \n" +" result1.x += dot(a1_trans,b0);\n" +" result1.y += dot(a1_trans,b1);\n" +" result1.z += dot(a1_trans,b2);\n" +" result1.w += dot(a1_trans,b3);\n" +" \n" +" result2.x += dot(a2_trans,b0);\n" +" result2.y += dot(a2_trans,b1);\n" +" result2.z += dot(a2_trans,b2);\n" +" result2.w += dot(a2_trans,b3);\n" +" \n" +" result3.x += dot(a3_trans,b0);\n" +" result3.y += dot(a3_trans,b1);\n" +" result3.z += dot(a3_trans,b2);\n" +" result3.w += dot(a3_trans,b3);\n" +" }\n" +" const int out_offset=(4*height_blocks_idx)*width_blocks+width_blocks_idx;\n" +" vstore4(CONVERT_FLOAT4(result0),out_offset,output_c);\n" +" if(4*height_blocks_idx+1 >= height) return;\n" +" vstore4(CONVERT_FLOAT4(result1),out_offset+width_blocks,output_c);\n" +" if(4*height_blocks_idx+2 >= height) return;\n" +" vstore4(CONVERT_FLOAT4(result2),out_offset+width_blocks*2,output_c);\n" +" if(4*height_blocks_idx+3 >= height) return;\n" +" vstore4(CONVERT_FLOAT4(result3),out_offset+width_blocks*3,output_c);\n" +"}\n" +; +#endif +const char* pooling = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void pooling(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,\n" +" __private const int2 input_shape,__private const int output_height,__private const int2 pad_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 kernel_shape,\n" +" __write_only image2d_t output,\n" +" __write_only image2d_t rediceOutput) {\n" +" const int output_channel_idx=get_global_id(0);\n" +" const int output_width_idx=get_global_id(1);\n" +" const int output_batch_height_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(output_channel_idx,output_width_idx,output_batch_height_idx);\n" +" const int output_width=global_size_dim1;\n" +" const int output_batch_idx=output_batch_height_idx/output_height;\n" +" const int output_height_idx=output_batch_height_idx-mul24(output_batch_idx,output_height);\n" +" const int input_start=mul24(output_batch_idx,input_shape.x);\n" +" const int input_height_start=mad24(output_height_idx,stride_shape.x,-pad_shape.x);\n" +" const int input_width_start=mad24(output_width_idx,stride_shape.y,-pad_shape.y);\n" +" const int input_channel_start=mul24(output_channel_idx,input_shape.y);\n" +"#ifdef POOL_AVG\n" +" FLOAT4 output_result=0;\n" +" for (int height=0; height= input_shape.x));\n" +" for (int width=0; width= input_shape.y));\n" +" FLOAT4 input_data=RI_F(input,SAMPLER,(int2)(input_width_idx,input_height_idx));\n" +" output_result=output_result+input_data;\n" +" }\n" +" }\n" +" const int kernel_height_start=max(0,input_height_start);\n" +" const int kernel_width_start=max(0,input_width_start);\n" +" const int kernel_height_end=min(input_height_start+kernel_shape.x,input_shape.x);\n" +" const int kernel_width_end=min(input_width_start+kernel_shape.y,input_shape.y);\n" +" #ifdef COUNT_INCLUDE_PADDING\n" +" const int block_size=(min(input_height_start+kernel_shape.x,input_shape.x+pad_shape.x)-input_height_start)*(min(input_width_start+kernel_shape.y,input_shape.y+pad_shape.y)-input_width_start);\n" +" #else\n" +" const int block_size=mul24((kernel_height_end-kernel_height_start),(kernel_width_end-kernel_width_start));\n" +" #endif\n" +" const FLOAT block_float_req=(FLOAT)1.0f/(FLOAT)block_size;\n" +" output_result=output_result*block_float_req;\n" +"#else\n" +" FLOAT4 output_result=(FLOAT4)(-FLT_MAX);\n" +" #if RETURN_REDICE\n" +" int4 redice=(int4)0;\n" +" #endif\n" +" for (int height=0; height= input_shape.x));\n" +" if (input_height_idx != -1) {\n" +" for (int width=0; width= input_shape.y));\n" +" if (input_width_idx != -1) {\n" +" FLOAT4 input_data=RI_F(input,SAMPLER,(int2)(input_width_idx,input_height_idx));\n" +" #if RETURN_REDICE\n" +" redice=input_data>output_result ? (int4)((input_height_start+height)*input_shape.y+input_width_start+width) : redice;\n" +" #endif\n" +" output_result=fmax(output_result,input_data);\n" +" }\n" +" }\n" +" }\n" +" }\n" +"#endif\n" +" const int output_channel_width_idx=mad24(output_channel_idx,output_width,output_width_idx);\n" +" WI_F(output,(int2)(output_channel_width_idx,output_batch_height_idx),output_result);\n" +" #if RETURN_REDICE\n" +" WI_F(rediceOutput,(int2)(output_channel_width_idx,output_batch_height_idx),CONVERT_FLOAT4(redice));\n" +" #endif\n" +"}\n" +"#ifdef LOCAL_SIZE\n" +"__kernel void global_pooling(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,\n" +" __private const int2 input_shape,__private const int output_height,__private const int2 pad_shape,\n" +" __private const int2 stride_shape,\n" +" __private const int2 kernel_shape,\n" +" __write_only image2d_t output,\n" +" __write_only image2d_t rediceOutput) {\n" +" const int local_id=get_local_id(0);\n" +" const int output_channel_idx=get_global_id(1);\n" +" const int output_batch_idx=get_global_id(2);\n" +"#ifdef POOL_AVG\n" +" FLOAT4 output_result=0;\n" +"#else\n" +" FLOAT4 output_result=(FLOAT4)(-FLT_MAX);\n" +"#if RETURN_REDICE\n" +" int4 redice=(int4)0;\n" +" int4 local rediceId[LOCAL_SIZE];\n" +"#endif\n" +"#endif\n" +" FLOAT4 local sum[LOCAL_SIZE];\n" +" int wc=output_channel_idx*input_shape.y;\n" +" int bh=output_batch_idx*input_shape.x;\n" +" for(int i=local_id; ioutput_result ? (int4)(i) : redice;\n" +"#endif\n" +"#endif\n" +" }\n" +" \n" +" sum[local_id]=output_result;\n" +"#if RETURN_REDICE\n" +" rediceId[local_id]=redice;\n" +"#endif\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" for(int i=LOCAL_SIZE/2; i>0; i /= 2){\n" +" if (local_idsum[local_id+i] ? rediceId[local_id] : rediceId[local_id+i];\n" +"#endif\n" +" }\n" +"#endif\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" }\n" +" output_result=sum[0];\n" +"#ifdef POOL_AVG\n" +" output_result /= (input_shape.x*input_shape.y);\n" +"#endif\n" +" WI_F(output,(int2)(output_channel_idx,output_batch_idx),output_result);\n" +" #if RETURN_REDICE\n" +" redice=rediceId[0];\n" +" WI_F(rediceOutput,(int2)(output_channel_idx,output_batch_idx),CONVERT_FLOAT4(redice));\n" +" #endif\n" +"}\n" +"#endif\n" +; +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* conv_2d_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__kernel\n" +"void conv_2d_1x1_c4h1w4(GLOBAL_SIZE_2_DIMS __private const int out_w_blocks,\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *kernel_ptr,\n" +" __global const FLOAT *bias_ptr,\n" +" __global FLOAT *output,\n" +" __private const int in_c_block,\n" +" __private const int out_h,\n" +" __private const int out_w,\n" +" __private const int out_c_block) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h; // equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_h; // equal to in_h_idx\n" +" const int out_w4_idx=mul24(out_w_idx,4);\n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias_ptr));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" COMPUTE_FLOAT4 out2=out0;\n" +" COMPUTE_FLOAT4 out3=out0;\n" +" const int intput_width_idx0=out_w4_idx;\n" +" \n" +" int offset=mul24(out_c_idx,in_c_block) << 2;\n" +" int inp_offset=(((out_b_idx*in_c_block)*out_h+out_h_idx)* out_w+intput_width_idx0) << 2;\n" +" \n" +" const int inp_add=out_h*out_w*4;\n" +" for (ushort in_channel_block_idx=0; in_channel_block_idx= 4) {\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +" } else if (remain == 3) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2,output+out_offset);\n" +" } else if (remain == 2) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_1x1_c8h1w4(GLOBAL_SIZE_2_DIMS __private const int out_w_blocks,\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *kernel_ptr,\n" +" __global const FLOAT *bias_ptr,\n" +" __global FLOAT *output,\n" +" __private const int in_c_block,\n" +" __private const int out_h,\n" +" __private const int out_w,\n" +" __private const int out_c_block) {\n" +" const int out_c_w_idx=get_global_id(0); //c/8 w/4\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_h;//equal to in_h_idx\n" +" const int out_w4_idx=mul24(out_w_idx,4);\n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx<<1,bias_ptr));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" COMPUTE_FLOAT4 out2=out0;\n" +" COMPUTE_FLOAT4 out3=out0;\n" +" \n" +" COMPUTE_FLOAT4 out4=CONVERT_COMPUTE_FLOAT4(vload4((out_c_idx<<1)+1,bias_ptr));\n" +" COMPUTE_FLOAT4 out5=out4;\n" +" COMPUTE_FLOAT4 out6=out4;\n" +" COMPUTE_FLOAT4 out7=out4;\n" +" const int intput_width_idx0=out_w4_idx;\n" +" \n" +" for (int in_channel_block_idx=0; in_channel_block_idx= 4) {\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,_tempoutput);\n" +" } else if (remain == 3) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,_tempoutput);\n" +" vstore4(CONVERT_FLOAT4(out2),2,_tempoutput);\n" +" } else if (remain == 2) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,_tempoutput);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(out0),0,_tempoutput);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx*2+1 >= out_c_block) {\n" +" return;\n" +" }\n" +"#endif\n" +" if (remain >= 4) {\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out4,out5,out6,out7)),0,_tempoutput1);\n" +" } else if (remain == 3) {\n" +" vstore8(CONVERT_FLOAT8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5))),0,_tempoutput1);\n" +" vstore4(CONVERT_FLOAT4(out6),2,_tempoutput1);\n" +" } else if (remain == 2) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5)),0,_tempoutput1);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(out4),0,_tempoutput1);\n" +" }\n" +"#else\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,_tempoutput);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx*2+1 >= out_c_block) {\n" +" return;\n" +" }\n" +"#endif\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out4,out5,out6,out7)),0,_tempoutput1);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_1x1_c8h1w2(GLOBAL_SIZE_2_DIMS __private const int out_w_blocks,\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *kernel_ptr,\n" +" __global const FLOAT *bias_ptr,\n" +" __global FLOAT *output,\n" +" __private const int in_c_block,\n" +" __private const int out_h,\n" +" __private const int out_w,\n" +" __private const int out_c_block) { // oc/4\n" +" const int out_c_w_idx=get_global_id(0); //c/8 w/4\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_h;//equal to in_h_idx\n" +" \n" +" const int out_w2_idx=mul24(out_w_idx,2);\n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx<<1,bias_ptr));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" \n" +" COMPUTE_FLOAT4 out4=CONVERT_COMPUTE_FLOAT4(vload4((out_c_idx<<1)+1,bias_ptr));\n" +" COMPUTE_FLOAT4 out5=out4;\n" +" const int intput_width_idx0=out_w2_idx;\n" +" \n" +" for (int in_channel_block_idx=0; in_channel_block_idx= 2) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,_tempoutput);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(out0),0,_tempoutput);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx*2+1 >= out_c_block) {\n" +" return;\n" +" }\n" +"#endif\n" +" if (remain >= 2) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5)),0,_tempoutput1);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(out4),0,_tempoutput1);\n" +" }\n" +"#else\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,_tempoutput);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx*2+1 >= out_c_block) {\n" +" return;\n" +" }\n" +"#endif\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5)),0,_tempoutput1);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_1x1_c4h1w1(GLOBAL_SIZE_2_DIMS __private const int out_w_blocks,\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *kernel_ptr,\n" +" __global const FLOAT *bias_ptr,\n" +" __global FLOAT *output,\n" +" __private const int in_c_block,\n" +" __private const int out_h,\n" +" __private const int out_w,\n" +" __private const int out_c_block) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w;\n" +" const int out_w_idx=out_c_w_idx % out_w;\n" +" const int out_b_idx=out_b_h_idx/out_h;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_h;//equal to in_h_idx\n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias_ptr));\n" +" const int intput_width_idx0=out_w_idx;\n" +" \n" +" for (int in_channel_block_idx=0; in_channel_block_idx= 2) {\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" } else if (remain == 1) {\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_c4h1w1(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *weight,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_hw.y;\n" +" const int out_w_idx=out_c_w_idx % out_hw.y;\n" +" const int out_b_idx=out_b_h_idx/out_hw.x;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" \n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" \n" +" const int in_w_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_h_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" \n" +" const int kw_start=select(0,(-in_w_idx_base+dilate_hw.y-1)/dilate_hw.y,in_w_idx_base<0);\n" +" const int kh_start=select(0,(-in_h_idx_base+dilate_hw.x-1)/dilate_hw.x,in_h_idx_base<0);\n" +" const int in_w_idx_start=mad24(kw_start,dilate_hw.y,in_w_idx_base);\n" +" const int in_w_idx_end=min(mad24(filter_hw.y,dilate_hw.y,in_w_idx_base),in_hw.y);\n" +" \n" +" const int in_h_idx_start=mad24(kh_start,dilate_hw.x,in_h_idx_base);\n" +" const int in_h_idx_end=min(mad24(filter_hw.x,dilate_hw.x,in_h_idx_base),in_hw.x);\n" +" \n" +" const int weight_oc_offset=out_c_blocks*filter_hw.x*filter_hw.y*4;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w0_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=(in_w1_idx<0 || in_w1_idx >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w1_idx,input+inp_offset_base));\n" +" \n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset));\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset));\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset*2));\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset*3));\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" if(out_w_idx+1 >= out_hw.y) return;\n" +" vstore4(CONVERT_FLOAT4(out1),1,output+out_offset);\n" +"#else\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_c4h1w4(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *weight,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=(out_c_w_idx % out_w_blocks) << 2;\n" +" const int out_b_idx=out_b_h_idx/out_hw.x;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" COMPUTE_FLOAT4 out2=out0;\n" +" COMPUTE_FLOAT4 out3=out0;\n" +" const int in_w0_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_w1_idx_base=in_w0_idx_base+stride_hw.y;\n" +" const int in_w2_idx_base=in_w1_idx_base+stride_hw.y;\n" +" const int in_w3_idx_base=in_w2_idx_base+stride_hw.y;\n" +" const int in_h_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" \n" +" const int kh_start=select(0,(-in_h_idx_base+dilate_hw.x-1)/dilate_hw.x,in_h_idx_base<0);\n" +" const int in_h_idx_start=mad24(kh_start,dilate_hw.x,in_h_idx_base);\n" +" const int in_h_idx_end=min(mad24(filter_hw.x,dilate_hw.x,in_h_idx_base),in_hw.x);\n" +" \n" +" const int weight_oc_offset=out_c_blocks*filter_hw.x*filter_hw.y*4;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w0_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=(in_w1_idx<0 || in_w1_idx >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w1_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=(in_w2_idx<0 || in_w2_idx >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w2_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=(in_w3_idx<0 || in_w3_idx >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w3_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset));\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset));\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset*2));\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset*3));\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.y-out_w_idx;\n" +" if (remain >= 4) {\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_c4h4w1(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *weight,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=out_c_w_idx/out_w_blocks;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h_blocks;//equal to in_b_idx\n" +" const int out_h_idx=(out_b_h_idx % out_h_blocks) << 2;\n" +" \n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" COMPUTE_FLOAT4 out2=out0;\n" +" COMPUTE_FLOAT4 out3=out0;\n" +" const int in_w_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_h0_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" const int in_h1_idx_base=in_h0_idx_base+stride_hw.x;\n" +" const int in_h2_idx_base=in_h1_idx_base+stride_hw.x;\n" +" const int in_h3_idx_base=in_h2_idx_base+stride_hw.x;\n" +" \n" +" const int kw_start=select(0,(-in_w_idx_base+dilate_hw.y-1)/dilate_hw.y,in_w_idx_base<0);\n" +" const int in_w_idx_start=mad24(kw_start,dilate_hw.y,in_w_idx_base);\n" +" const int in_w_idx_end=min(mad24(filter_hw.y,dilate_hw.y,in_w_idx_base),in_hw.y);\n" +" \n" +" const int weight_oc_offset=out_c_blocks*filter_hw.x*filter_hw.y*4;\n" +" const int in_hw_size=in_hw.x*in_hw.y;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h0_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=(in_h1_idx<0 || in_h1_idx >= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h1_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=(in_h2_idx<0 || in_h2_idx >= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h2_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=(in_h3_idx<0 || in_h3_idx >= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h3_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset));\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset));\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset*2));\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset*3));\n" +" \n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" const int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.x-out_h_idx;\n" +" if(remain >= 4){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_c8h4w1(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *weight,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h_blocks;//equal to in_b_idx\n" +" const int out_h_idx=(out_b_h_idx % out_h_blocks) << 2;\n" +" \n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" COMPUTE_FLOAT4 out2=out0;\n" +" COMPUTE_FLOAT4 out3=out0;\n" +" COMPUTE_FLOAT4 out4=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx+1,bias));\n" +" COMPUTE_FLOAT4 out5=out4;\n" +" COMPUTE_FLOAT4 out6=out4;\n" +" COMPUTE_FLOAT4 out7=out4;\n" +" const int in_w_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_h0_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" const int in_h1_idx_base=in_h0_idx_base+stride_hw.x;\n" +" const int in_h2_idx_base=in_h1_idx_base+stride_hw.x;\n" +" const int in_h3_idx_base=in_h2_idx_base+stride_hw.x;\n" +" \n" +" const int kw_start=select(0,(-in_w_idx_base+dilate_hw.y-1)/dilate_hw.y,in_w_idx_base<0);\n" +" const int in_w_idx_start=mad24(kw_start,dilate_hw.y,in_w_idx_base);\n" +" const int in_w_idx_end=min(mad24(filter_hw.y,dilate_hw.y,in_w_idx_base),in_hw.y);\n" +" \n" +" const int weight_oc_offset=filter_hw.x*filter_hw.y*4;\n" +" const int weight_ic_offset=out_c_blocks*weight_oc_offset;\n" +" const int in_hw_size=in_hw.x*in_hw.y;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h0_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=(in_h1_idx<0 || in_h1_idx >= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h1_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=(in_h2_idx<0 || in_h2_idx >= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h2_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=(in_h3_idx<0 || in_h3_idx >= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h3_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset));\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset));\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset*2));\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset*3));\n" +" \n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +" weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset));\n" +" weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset));\n" +" weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*2));\n" +" weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*3));\n" +" out4=mad(in0.x,weight0,out4);\n" +" out4=mad(in0.y,weight1,out4);\n" +" out4=mad(in0.z,weight2,out4);\n" +" out4=mad(in0.w,weight3,out4);\n" +" \n" +" out5=mad(in1.x,weight0,out5);\n" +" out5=mad(in1.y,weight1,out5);\n" +" out5=mad(in1.z,weight2,out5);\n" +" out5=mad(in1.w,weight3,out5);\n" +" \n" +" out6=mad(in2.x,weight0,out6);\n" +" out6=mad(in2.y,weight1,out6);\n" +" out6=mad(in2.z,weight2,out6);\n" +" out6=mad(in2.w,weight3,out6);\n" +" \n" +" out7=mad(in3.x,weight0,out7);\n" +" out7=mad(in3.y,weight1,out7);\n" +" out7=mad(in3.z,weight2,out7);\n" +" out7=mad(in3.w,weight3,out7);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +" out4=fmax(out4,(COMPUTE_FLOAT4)0);\n" +" out5=fmax(out5,(COMPUTE_FLOAT4)0);\n" +" out6=fmax(out6,(COMPUTE_FLOAT4)0);\n" +" out7=fmax(out7,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out4=clamp(out4,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out5=clamp(out5,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out6=clamp(out6,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out7=clamp(out7,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.x-out_h_idx;\n" +" if(remain >= 4){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" if(remain >= 4){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out7),3*out_hw.y,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2*out_hw.y,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),3*out_hw.y,output+out_offset);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out5),out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2*out_hw.y,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out7),3*out_hw.y,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_c8h2w1(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *weight,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=out_c_w_idx % out_w_blocks;\n" +" const int out_b_idx=out_b_h_idx/out_h_blocks;//equal to in_b_idx\n" +" const int out_h_idx=(out_b_h_idx % out_h_blocks) << 1;\n" +" \n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" COMPUTE_FLOAT4 out2=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx+1,bias));\n" +" COMPUTE_FLOAT4 out3=out2;\n" +" const int in_w_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_h0_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" const int in_h1_idx_base=in_h0_idx_base+stride_hw.x;\n" +" \n" +" const int kw_start=select(0,(-in_w_idx_base+dilate_hw.y-1)/dilate_hw.y,in_w_idx_base<0);\n" +" const int in_w_idx_start=mad24(kw_start,dilate_hw.y,in_w_idx_base);\n" +" const int in_w_idx_end=min(mad24(filter_hw.y,dilate_hw.y,in_w_idx_base),in_hw.y);\n" +" \n" +" const int weight_oc_offset=filter_hw.x*filter_hw.y*4;\n" +" const int weight_ic_offset=out_c_blocks*weight_oc_offset;\n" +" const int in_hw_size=in_hw.x*in_hw.y;\n" +" // weight: [ic/4,oc,4],loop: ic/4\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h0_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=(in_h1_idx<0 || in_h1_idx >= in_hw_size) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_h1_idx+fw,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset));\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset));\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset*2));\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset*3));\n" +" \n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset));\n" +" weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset));\n" +" weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*2));\n" +" weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*3));\n" +" \n" +" out2=mad(in0.x,weight0,out2);\n" +" out2=mad(in0.y,weight1,out2);\n" +" out2=mad(in0.z,weight2,out2);\n" +" out2=mad(in0.w,weight3,out2);\n" +" \n" +" out3=mad(in1.x,weight0,out3);\n" +" out3=mad(in1.y,weight1,out3);\n" +" out3=mad(in1.z,weight2,out3);\n" +" out3=mad(in1.w,weight3,out3);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.x-out_h_idx;\n" +" if(remain >= 2){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" if(remain >= 2){\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),out_hw.y,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out1),out_hw.y,output+out_offset);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks){\n" +" return;\n" +" }\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore4(CONVERT_FLOAT4(out2),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out3),out_hw.y,output+out_offset);\n" +"#endif\n" +"}\n" +"__kernel\n" +"void conv_2d_c8h1w4(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input,\n" +" __global const FLOAT *weight,\n" +" __global const FLOAT *bias,\n" +" __global FLOAT *output,\n" +" __private const int2 in_hw,\n" +" __private const int inChannel,\n" +" __private const int in_c_blocks,\n" +" __private const int2 out_hw,\n" +" __private const int2 filter_hw,\n" +" __private const int2 stride_hw,\n" +" __private const int2 pad_hw,\n" +" __private const int2 dilate_hw,\n" +" __private const int out_w_blocks,\n" +" __private const int out_c_blocks,\n" +" __private const int out_h_blocks) {\n" +" const int out_c_w_idx=get_global_id(0); //c/4 w\n" +" const int out_b_h_idx=get_global_id(1); //b h\n" +" DEAL_NON_UNIFORM_DIM2(out_c_w_idx,out_b_h_idx);\n" +" const int out_c_idx=(out_c_w_idx/out_w_blocks) << 1;\n" +" const int out_w_idx=(out_c_w_idx % out_w_blocks) << 2;\n" +" const int out_b_idx=out_b_h_idx/out_hw.x;//equal to in_b_idx\n" +" const int out_h_idx=out_b_h_idx % out_hw.x;\n" +" \n" +" COMPUTE_FLOAT4 out0=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx,bias));\n" +" COMPUTE_FLOAT4 out1=out0;\n" +" COMPUTE_FLOAT4 out2=out0;\n" +" COMPUTE_FLOAT4 out3=out0;\n" +" \n" +" COMPUTE_FLOAT4 out4=CONVERT_COMPUTE_FLOAT4(vload4(out_c_idx+1,bias));\n" +" COMPUTE_FLOAT4 out5=out4;\n" +" COMPUTE_FLOAT4 out6=out4;\n" +" COMPUTE_FLOAT4 out7=out4;\n" +" const int in_w0_idx_base=mad24(out_w_idx,stride_hw.y,-pad_hw.y);\n" +" const int in_w1_idx_base=in_w0_idx_base+stride_hw.y;\n" +" const int in_w2_idx_base=in_w1_idx_base+stride_hw.y;\n" +" const int in_w3_idx_base=in_w2_idx_base+stride_hw.y;\n" +" const int in_h_idx_base=mad24(out_h_idx,stride_hw.x,-pad_hw.x);\n" +" \n" +" const int kh_start=select(0,(-in_h_idx_base+dilate_hw.x-1)/dilate_hw.x,in_h_idx_base<0);\n" +" const int in_h_idx_start=mad24(kh_start,dilate_hw.x,in_h_idx_base);\n" +" const int in_h_idx_end=min(mad24(filter_hw.x,dilate_hw.x,in_h_idx_base),in_hw.x);\n" +" \n" +" const int weight_oc_offset=filter_hw.x*filter_hw.y*4;\n" +" const int weight_ic_offset=out_c_blocks*weight_oc_offset;\n" +" for(ushort in_c_idx=0; in_c_idx= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w0_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in1=(in_w1_idx<0 || in_w1_idx >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w1_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in2=(in_w2_idx<0 || in_w2_idx >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w2_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 in3=(in_w3_idx<0 || in_w3_idx >= in_hw.y) ? (COMPUTE_FLOAT4)0 : CONVERT_COMPUTE_FLOAT4(vload4(in_w3_idx,input+inp_offset_base));\n" +" COMPUTE_FLOAT4 weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset));\n" +" COMPUTE_FLOAT4 weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset));\n" +" COMPUTE_FLOAT4 weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset*2));\n" +" COMPUTE_FLOAT4 weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_ic_offset*3));\n" +" out0=mad(in0.x,weight0,out0);\n" +" out0=mad(in0.y,weight1,out0);\n" +" out0=mad(in0.z,weight2,out0);\n" +" out0=mad(in0.w,weight3,out0);\n" +" \n" +" out1=mad(in1.x,weight0,out1);\n" +" out1=mad(in1.y,weight1,out1);\n" +" out1=mad(in1.z,weight2,out1);\n" +" out1=mad(in1.w,weight3,out1);\n" +" \n" +" out2=mad(in2.x,weight0,out2);\n" +" out2=mad(in2.y,weight1,out2);\n" +" out2=mad(in2.z,weight2,out2);\n" +" out2=mad(in2.w,weight3,out2);\n" +" \n" +" out3=mad(in3.x,weight0,out3);\n" +" out3=mad(in3.y,weight1,out3);\n" +" out3=mad(in3.z,weight2,out3);\n" +" out3=mad(in3.w,weight3,out3);\n" +" \n" +" weight0=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset));\n" +" weight1=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset));\n" +" weight2=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*2));\n" +" weight3=CONVERT_COMPUTE_FLOAT4(vload4(0,weight+weight_offset+weight_oc_offset+weight_ic_offset*3));\n" +" \n" +" out4=mad(in0.x,weight0,out4);\n" +" out4=mad(in0.y,weight1,out4);\n" +" out4=mad(in0.z,weight2,out4);\n" +" out4=mad(in0.w,weight3,out4);\n" +" \n" +" out5=mad(in1.x,weight0,out5);\n" +" out5=mad(in1.y,weight1,out5);\n" +" out5=mad(in1.z,weight2,out5);\n" +" out5=mad(in1.w,weight3,out5);\n" +" \n" +" out6=mad(in2.x,weight0,out6);\n" +" out6=mad(in2.y,weight1,out6);\n" +" out6=mad(in2.z,weight2,out6);\n" +" out6=mad(in2.w,weight3,out6);\n" +" \n" +" out7=mad(in3.x,weight0,out7);\n" +" out7=mad(in3.y,weight1,out7);\n" +" out7=mad(in3.z,weight2,out7);\n" +" out7=mad(in3.w,weight3,out7);\n" +" \n" +" weight_offset += 4;\n" +" }\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" out0=fmax(out0,(COMPUTE_FLOAT4)0);\n" +" out1=fmax(out1,(COMPUTE_FLOAT4)0);\n" +" out2=fmax(out2,(COMPUTE_FLOAT4)0);\n" +" out3=fmax(out3,(COMPUTE_FLOAT4)0);\n" +" out4=fmax(out4,(COMPUTE_FLOAT4)0);\n" +" out5=fmax(out5,(COMPUTE_FLOAT4)0);\n" +" out6=fmax(out6,(COMPUTE_FLOAT4)0);\n" +" out7=fmax(out7,(COMPUTE_FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" out0=clamp(out0,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out1=clamp(out1,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out2=clamp(out2,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out3=clamp(out3,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out4=clamp(out4,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out5=clamp(out5,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out6=clamp(out6,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +" out7=clamp(out7,(COMPUTE_FLOAT4)0,(COMPUTE_FLOAT4)6);\n" +"#endif\n" +" int out_offset=(((out_b_idx*out_c_blocks+out_c_idx)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +"#ifdef BLOCK_LEAVE\n" +" const int remain=out_hw.y-out_w_idx;\n" +" if(remain >= 4){\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out2),2,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out0,out1)),0,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out0),0,output+out_offset);\n" +" }\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks)return;\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" if(remain >= 4){\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out4,out5,out6,out7)),0,output+out_offset);\n" +" }else if(remain == 3){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5)),0,output+out_offset);\n" +" vstore4(CONVERT_FLOAT4(out6),2,output+out_offset);\n" +" }else if(remain == 2){\n" +" vstore8(CONVERT_FLOAT8((COMPUTE_FLOAT8)(out4,out5)),0,output+out_offset);\n" +" }else if(remain == 1){\n" +" vstore4(CONVERT_FLOAT4(out4),0,output+out_offset);\n" +" }\n" +"#else\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out0,out1,out2,out3)),0,output+out_offset);\n" +"#ifdef CHANNEL_LEAVE\n" +" if(out_c_idx+1 >= out_c_blocks)return;\n" +"#endif\n" +" out_offset=(((out_b_idx*out_c_blocks+out_c_idx+1)*out_hw.x+out_h_idx)*out_hw.y+out_w_idx)*4;\n" +" vstore16(CONVERT_FLOAT16((COMPUTE_FLOAT16)(out4,out5,out6,out7)),0,output+out_offset);\n" +"#endif\n" +"}\n" +; +#endif +const char* buffer_to_image = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"// convert kernel : from buffer(oi ) to image(oc,ic/4)\n" +"__kernel void conv2d1x1_opt_filter_buffer_to_image(GLOBAL_SIZE_2_DIMS __global const FLOAT *input_ptr,\n" +" __private const int input_channel,__private const int2 kernel_shape,__private const int ic_h_w_size,\n" +" __private const int height_width_size,__write_only image2d_t output) {\n" +" \n" +" int ic_4_idx=get_global_id(0); // ic/4\n" +" int oc_idx=get_global_id(1); // oc\n" +" DEAL_NON_UNIFORM_DIM2(ic_4_idx,oc_idx);\n" +" const int ic_idx=ic_4_idx*4;\n" +" const int buffer_offset=oc_idx*input_channel+ic_idx;\n" +" \n" +" FLOAT4 output_values=0;\n" +" if (ic_idx= 4) {\n" +" output_values.x=*(input_ptr+buffer_offset);\n" +" output_values.y=*(input_ptr+buffer_offset+1);\n" +" output_values.z=*(input_ptr+buffer_offset+2);\n" +" output_values.w=*(input_ptr+buffer_offset+3);\n" +" } else if (remain_channel == 3) {\n" +" output_values.x=*(input_ptr+buffer_offset);\n" +" output_values.y=*(input_ptr+buffer_offset+1);\n" +" output_values.z=*(input_ptr+buffer_offset+2);\n" +" output_values.w=0;\n" +" } else if (remain_channel == 2) {\n" +" output_values.x=*(input_ptr+buffer_offset);\n" +" output_values.y=*(input_ptr+buffer_offset+1);\n" +" output_values.z=0;\n" +" output_values.w=0;\n" +" } else if (remain_channel == 1) {\n" +" output_values.x=*(input_ptr+buffer_offset);\n" +" output_values.y=0;\n" +" output_values.z=0;\n" +" output_values.w=0;\n" +" }\n" +" }\n" +" WI_F(output,(int2)(ic_4_idx,oc_idx),output_values);\n" +"}\n" +"// convert kernel : from buffer(oihw) to image(oc/4 h w ,ic oc4)\n" +"__kernel void conv2d_filter_buffer_to_image(GLOBAL_SIZE_2_DIMS\n" +" #ifdef BUFFER_INP_FP32\n" +" __global const float *input_ptr,\n" +" #else\n" +" __global const FLOAT *input_ptr,\n" +" #endif\n" +" __private const int output_channel,__private const int2 kernel_shape,__private const int ic_h_w_size,\n" +" __private const int height_width_size,__write_only image2d_t output) {\n" +" int image_width_idx=get_global_id(0); // ic\n" +" int image_height_idx=get_global_id(1); // oc/4 h w\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int input_channel_4_idx=image_width_idx;\n" +" const int output_channel_4_idx=(image_height_idx/height_width_size)*4;\n" +" const int height_width_idx=image_height_idx % height_width_size;\n" +" const int buffer_height_idx=height_width_idx/kernel_shape.y;\n" +" const int buffer_width_idx=height_width_idx % kernel_shape.y;\n" +" const int buffer_offset=output_channel_4_idx*ic_h_w_size+input_channel_4_idx*height_width_size +\n" +" buffer_height_idx*kernel_shape.y+buffer_width_idx;\n" +" FLOAT4 output_values=0;\n" +" if (output_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.w=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" WI_F(output,(int2)(image_width_idx,image_height_idx),output_values);\n" +"}\n" +"// only for debug\n" +"// convert kernel : from image(oc/4 h w ,ic oc4) to buffer(oihw)\n" +"__kernel void conv2d_filter_image_to_buffer(GLOBAL_SIZE_2_DIMS __global FLOAT *output_ptr,\n" +" __private const int output_channel,__private const int2 kernel_shape,\n" +" __private const int ic_h_w_size,\n" +" __private const int height_width_size,__read_only image2d_t input_ptr) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int input_channel_4_idx=image_width_idx;\n" +" const int output_channel_4_idx=image_height_idx/height_width_size*4;\n" +" const int height_width_idx=image_height_idx % height_width_size;\n" +" const int buffer_height_idx=height_width_idx/kernel_shape.y;\n" +" const int buffer_width_idx=height_width_idx % kernel_shape.y;\n" +" const int buffer_offset=output_channel_4_idx*ic_h_w_size+input_channel_4_idx*height_width_size +\n" +" buffer_height_idx*kernel_shape.y+buffer_width_idx;\n" +" if (output_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_ptr[offset]=values.x;\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_ptr[offset]=values.y;\n" +" offset += ic_h_w_size;\n" +" output_ptr[offset]=values.z;\n" +" offset += ic_h_w_size;\n" +" output_ptr[offset]=values.w;\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_ptr[offset]=values.x;\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_ptr[offset]=values.y;\n" +" offset += ic_h_w_size;\n" +" output_ptr[offset]=values.z;\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_ptr[offset]=values.x;\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_ptr[offset]=values.y;\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_ptr[offset]=values.x;\n" +" }\n" +" }\n" +"}\n" +"// convert kernel from buffer(mihw) to image(ic/4,ic4 h w m)\n" +"// but now dw only support m == 1\n" +"__kernel void dw_filter_buffer_to_image(GLOBAL_SIZE_2_DIMS\n" +" #ifdef BUFFER_INP_FP32\n" +" __global const float *input_ptr,\n" +" #else\n" +" __global const FLOAT *input_ptr,\n" +" #endif\n" +" __private const int4 kernel_shape,\n" +" __private const int height_width_size,__write_only image2d_t output) {\n" +" const int image_width_idx=get_global_id(0);\n" +" const int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" FLOAT4 output_values=0;\n" +" if (kernel_shape.x == 1) {\n" +" const int input_channel_4_idx=image_height_idx*4;\n" +" const int buffer_height_idx=image_width_idx/kernel_shape.w;\n" +" const int buffer_width_idx=image_width_idx % kernel_shape.w;\n" +" const int buffer_offset =\n" +" mad24(mad24(input_channel_4_idx,kernel_shape.z,buffer_height_idx),kernel_shape.w,buffer_width_idx);\n" +" const int remain_channel=kernel_shape.y-input_channel_4_idx;\n" +" if (input_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.w=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" }\n" +" WI_F(output,(int2)(image_width_idx,image_height_idx),output_values);\n" +"}\n" +"__kernel void nc4hw4_buffer_to_image(GLOBAL_SIZE_2_DIMS\n" +" __global const INPUT_TYPE *input_ptr,\n" +" __private const int2 output_shape,\n" +" __private const int batch_size,__write_only image2d_t output) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/output_shape.x;\n" +" const int height_idx=image_height_idx % output_shape.x;\n" +" const int width_idx=image_width_idx % output_shape.y;\n" +" const int channel_block_idx=image_width_idx/output_shape.y;\n" +" int buffer_offset =\n" +" (((batch_idx+channel_block_idx*batch_size)*output_shape.x+height_idx)*output_shape.y+width_idx)*4;\n" +" int2 coord=(int2)(image_width_idx,image_height_idx);\n" +" WI_DATA(output,coord,CONVERT_OUTPUT_I4(vload4(0,input_ptr+buffer_offset)));\n" +"}\n" +"__kernel void image_to_nc4hw4_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int2 output_shape,\n" +" __private const int batch_size,\n" +" __read_only image2d_t input_ptr) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/output_shape.x;\n" +" const int height_idx=image_height_idx % output_shape.x;\n" +" const int width_idx=image_width_idx % output_shape.y;\n" +" int channel_block_idx=image_width_idx/output_shape.y;\n" +" int buffer_offset =\n" +" (((batch_idx+channel_block_idx*batch_size)*output_shape.x+height_idx)*output_shape.y+width_idx)*4;\n" +" int2 coord=(int2)(image_width_idx,image_height_idx);\n" +" vstore4(CONVERT_OUTPUT4(RI_DATA(input_ptr,SAMPLER,coord)),0,output+buffer_offset);\n" +"}\n" +"__kernel void nhwc_buffer_to_image(GLOBAL_SIZE_2_DIMS\n" +" __global const INPUT_TYPE *input_ptr,\n" +" __private const int height,\n" +" __private const int width,__private const int channels,\n" +" __write_only image2d_t output) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_4_idx=(image_width_idx/width) << 2;\n" +" const int buffer_offset=((batch_idx*height+height_idx)*width+width_idx)*channels+channel_4_idx;\n" +" const int remain_channel=channels-channel_4_idx;\n" +" INPUT_TYPE4 values=vload4(0,input_ptr+buffer_offset);\n" +" if (remain_channel == 3) {\n" +" values.w=0;\n" +" } else if (remain_channel == 2) {\n" +" values.z=0;\n" +" values.w=0;\n" +" } else if (remain_channel == 1) {\n" +" values.y=0;\n" +" values.z=0;\n" +" values.w=0;\n" +" }\n" +" WI_DATA(output,(int2)(image_width_idx,image_height_idx),CONVERT_OUTPUT_I4(values));\n" +"}\n" +"__kernel void nchw_buffer_to_image(GLOBAL_SIZE_2_DIMS\n" +" __global const INPUT_TYPE *input_ptr,\n" +" __private const int height,__private const int width,__private const int channels,\n" +" __write_only image2d_t output) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_4_idx=image_width_idx/width << 2;\n" +" const int buffer_offset=((batch_idx*channels+channel_4_idx)*height+height_idx)*width+width_idx;\n" +" const int remain_channel=channels-channel_4_idx;\n" +" const int height_width_size=height*width;\n" +" INPUT_TYPE4 output_values=0;\n" +" if (remain_channel >= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.y=*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.z=*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.w=*(input_ptr+offset);\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.y=*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.z=*(input_ptr+offset);\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.y=*(input_ptr+offset);\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=*(input_ptr+offset);\n" +" }\n" +" WI_DATA(output,(int2)(image_width_idx,image_height_idx),CONVERT_OUTPUT_I4(output_values));\n" +"}\n" +"__kernel void image_to_nhwc_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int height,__private const int width,\n" +" __private const int channels,\n" +" __read_only image2d_t input_ptr) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_4_idx=(image_width_idx/width) << 2;\n" +" const int buffer_offset=((batch_idx*height+height_idx)*width+width_idx)*channels+channel_4_idx;\n" +" int2 coord=(int2)(image_width_idx,image_height_idx);\n" +" \n" +" INPUT_TYPE_I4 values=RI_DATA(input_ptr,SAMPLER,coord);\n" +" const int remain_channel=channels-channel_4_idx;\n" +" if (remain_channel >= 4) {\n" +" vstore4(CONVERT_OUTPUT4(values),0,output+buffer_offset);\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.z;\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" }\n" +"}\n" +"__kernel void image_to_nchw_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int height,__private const int width,\n" +" __private const int channels,\n" +" __read_only image2d_t input_ptr) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" int channel_4_idx=(image_width_idx/width)*4;\n" +" int buffer_offset=((batch_idx*channels+channel_4_idx)*height+height_idx)*width+width_idx;\n" +" \n" +" INPUT_TYPE_I4 values=RI_DATA(input_ptr,SAMPLER,(int2)(image_width_idx,image_height_idx));\n" +" const int height_width_size=height*width;\n" +" const int remain_channel=channels-channel_4_idx;\n" +" if (remain_channel >= 4) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.z;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.w;\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.z;\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" }\n" +"}\n" +"// convert arg as 4 alignment\n" +"__kernel void arg_buffer_to_image(GLOBAL_SIZE_2_DIMS __global const INPUT_TYPE *input_ptr,__private const int count,\n" +" __write_only image2d_t output) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int buffer_4_offset=image_width_idx << 2;\n" +" const int remain=count-buffer_4_offset;\n" +" int offset=buffer_4_offset;\n" +" INPUT_TYPE4 values=0;\n" +" if (remain >= 4) {\n" +" values=vload4(0,input_ptr+offset);\n" +" } else if (remain == 3) {\n" +" values.x=*(input_ptr+offset);\n" +" offset++;\n" +" values.y=*(input_ptr+offset);\n" +" offset++;\n" +" values.z=*(input_ptr+offset);\n" +" } else if (remain == 2) {\n" +" values.x=*(input_ptr+offset);\n" +" offset++;\n" +" values.y=*(input_ptr+offset);\n" +" } else if (remain == 1) {\n" +" values.x=*(input_ptr+offset);\n" +" }\n" +" WI_DATA(output,(int2)(image_width_idx,image_height_idx),CONVERT_OUTPUT_I4(values));\n" +"}\n" +"// only for debug\n" +"__kernel void arg_image_to_buffer(GLOBAL_SIZE_2_DIMS __global OUTPUT_TYPE *output,__private const int count,\n" +" __read_only image2d_t input_ptr) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int buffer_4_offset=image_width_idx << 2;\n" +" int2 coord=(int2)(image_width_idx,image_height_idx);\n" +" INPUT_TYPE_I4 values=RI_DATA(input_ptr,SAMPLER,coord);\n" +" const int remain=count-buffer_4_offset;\n" +" if (remain<4) {\n" +" switch (remain) {\n" +" case 3:\n" +" output[buffer_4_offset+2]=(OUTPUT_TYPE)values.s2;\n" +" case 2:\n" +" output[buffer_4_offset+1]=(OUTPUT_TYPE)values.s1;\n" +" case 1:\n" +" output[buffer_4_offset]=(OUTPUT_TYPE)values.s0;\n" +" }\n" +" } else {\n" +" vstore4(CONVERT_OUTPUT4(values),0,output+buffer_4_offset);\n" +" }\n" +" if (remain >= 4) {\n" +" vstore4(CONVERT_OUTPUT4(values),0,output+buffer_4_offset);\n" +" } else if (remain == 3) {\n" +" int offset=buffer_4_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.z;\n" +" } else if (remain == 2) {\n" +" int offset=buffer_4_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" } else if (remain == 1) {\n" +" int offset=buffer_4_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" }\n" +"}\n" +; +const char* winogradTransformDest2_3_1 = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void winogradTransformDest(__read_only image2d_t uInput,// 0\n" +" __read_only image2d_t uBias,__write_only image2d_t uOutput,\n" +" __private const int unitWidth,// 3\n" +" __private const int unitHeight,__private const int dstWidth,\n" +" __private const int dstHeight,// 6\n" +" __private const int dstChannelC4,__private const int batchOffset) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));\n" +" if (pos.x0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid> 2;\n" +" const int inside_remain=inside-((inside_v4-1) << 2);\n" +" COMPUTE_FLOAT4 in_sum=0;\n" +" int index=lid;\n" +" for(; index1) {\n" +" sum[lid]=sum[lid]+in_left.y;\n" +" }\n" +" if(inside_remain>2) {\n" +" sum[lid]=sum[lid]+in_left.z;\n" +" }\n" +" if(inside_remain>3) {\n" +" sum[lid]=sum[lid]+in_left.w;\n" +" }\n" +" }\n" +" \n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" for(int i=LOCAL_SIZE/2; i>0; i /= 2){\n" +" if (lid1) {\n" +" sum[lid]=sum[lid]+in_sum.y;\n" +" }\n" +" if(inside_remain>2) {\n" +" sum[lid]=sum[lid]+in_sum.z;\n" +" }\n" +" if(inside_remain>3) {\n" +" sum[lid]=sum[lid]+in_sum.w;\n" +" }\n" +" }\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" for(int i=LOCAL_SIZE/2; i>0; i /= 2){\n" +" if (lid= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void softmax_channel(GLOBAL_SIZE_3_DIMS\n" +" __global const FLOAT *input,\n" +" __global FLOAT *output,\n" +" __private const int remain_channels,\n" +" __private const int4 shape) {//NCHW\n" +" const int x=get_global_id(0);\n" +" const int w=get_global_id(1);\n" +" const int bh=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(x,w,bh);\n" +" \n" +" const int batch_idx=bh/shape.z;\n" +" const int height_idx=bh % shape.z;\n" +" const int offset=(((batch_idx*shape.y+0)*shape.z+height_idx)*shape.w+w)*4;\n" +"#if SOFTMAX_LOCAL_SIZE >= 4\n" +" int lid=get_local_id(0);\n" +" COMPUTE_FLOAT4 local sum[SOFTMAX_LOCAL_SIZE];\n" +" COMPUTE_FLOAT4 maxValue=(COMPUTE_FLOAT4)-FLT_MAX;\n" +" for (int i=lid; i0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid= 4\n" +" int lid=get_local_id(0);\n" +" COMPUTE_FLOAT4 local sum[SOFTMAX_LOCAL_SIZE];\n" +" \n" +" /*Compute Max */\n" +" COMPUTE_FLOAT4 maxValue=(COMPUTE_FLOAT4)(-FLT_MAX);\n" +" for (int i=lid; i0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid= 4\n" +" int lid=get_local_id(0);\n" +" COMPUTE_FLOAT4 local sum[SOFTMAX_LOCAL_SIZE];\n" +" \n" +" /*Compute Max */\n" +" COMPUTE_FLOAT4 maxValue=(COMPUTE_FLOAT4)(-FLT_MAX);\n" +" for (int i=lid; i0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid> 2;\n" +" #ifdef GATHER_INPUT_NHWC\n" +" int off_c=offset_value % offset_dst_shape.z; offset_value /= offset_dst_shape.z;\n" +" int off_w=offset_value % offset_dst_shape.x; offset_value /= offset_dst_shape.x;\n" +" int off_h=offset_value % offset_dst_shape.y;\n" +" int off_b=offset_value/offset_dst_shape.y;\n" +" #else\n" +" int off_w=offset_value % offset_dst_shape.x; offset_value /= offset_dst_shape.x;\n" +" int off_h=offset_value % offset_dst_shape.y; offset_value /= offset_dst_shape.y;\n" +" int off_c=offset_value % offset_dst_shape.z;\n" +" int off_b=offset_value/offset_dst_shape.z;\n" +" #endif\n" +" int real_dst_offset=(((off_b*off_c4_size+off_c/4)*offset_dst_shape.y+off_h)*offset_dst_shape.x+off_w)*4+off_c % 4;\n" +" index.x=offset_dst_ptr[real_dst_offset];\n" +" }\n" +" #endif\n" +" \n" +" #ifdef OFFSET_SRC\n" +" {\n" +" int offset_value=pos.z;\n" +" int off_c4_size=(offset_src_shape.z+3) >> 2;\n" +" #ifdef GATHER_INPUT_NHWC\n" +" int off_c=offset_value % offset_src_shape.z; offset_value /= offset_src_shape.z;\n" +" int off_w=offset_value % offset_src_shape.x; offset_value /= offset_src_shape.x;\n" +" int off_h=offset_value % offset_src_shape.y;\n" +" int off_b=offset_value/offset_src_shape.y;\n" +" #else\n" +" int off_w=offset_value % offset_src_shape.x; offset_value /= offset_src_shape.x;\n" +" int off_h=offset_value % offset_src_shape.y; offset_value /= offset_src_shape.y;\n" +" int off_c=offset_value % offset_src_shape.z;\n" +" int off_b=offset_value/offset_src_shape.z;\n" +" #endif\n" +" int real_src_offset=(((off_b*off_c4_size+off_c/4)*offset_src_shape.y+off_h)*offset_src_shape.x+off_w)*4+off_c % 4;\n" +" index.y=offset_src_ptr[real_src_offset];\n" +" }\n" +" #endif\n" +" \n" +" int2 offset=index*steps;\n" +" int src_offset=offset.y+stride_src.w+x*stride_src.x+y*stride_src.y+pos.y*stride_src.z;\n" +" int dst_offset=offset.x+stride_dst.w+x*stride_dst.x+y*stride_dst.y+pos.y*stride_dst.z;\n" +" int src_offsetC4,dst_offsetC4;\n" +" {\n" +"#ifdef GATHER_INPUT_NHWC\n" +" int c=src_offset % src_c4size.z; src_offset /= src_c4size.z;\n" +" int w=src_offset % src_c4size.x; src_offset /= src_c4size.x;\n" +" int h=src_offset % src_c4size.y;\n" +" int b=src_offset/src_c4size.y;\n" +" int c4_size=(src_c4size.z+3)/4;\n" +" src_offsetC4=(((b*c4_size+(c/4))*src_c4size.y+h)*src_c4size.x+w)*4+(c % 4);\n" +"#else\n" +" int w=src_offset % src_c4size.x; src_offset /= src_c4size.x;\n" +" int h=src_offset % src_c4size.y; src_offset /= src_c4size.y;\n" +" int c=src_offset % src_c4size.z;\n" +" int b=src_offset/src_c4size.z;\n" +" int c4_size=(src_c4size.z+3)/4;\n" +" src_offsetC4=(((b*c4_size+(c/4))*src_c4size.y+h)*src_c4size.x+w)*4+(c % 4);\n" +"#endif\n" +" }\n" +" {\n" +"#ifdef GATHER_OUTPUT_NHWC\n" +" int c=dst_offset % dst_c4size.z; dst_offset /= dst_c4size.z;\n" +" int w=dst_offset % dst_c4size.x; dst_offset /= dst_c4size.x;\n" +" int h=dst_offset % dst_c4size.y;\n" +" int b=dst_offset/dst_c4size.y;\n" +" int c4_size=(dst_c4size.z+3)/4;\n" +" dst_offsetC4=(((b*c4_size+(c/4))*dst_c4size.y+h)*dst_c4size.x+w)*4+(c % 4);\n" +"#else\n" +" int w=dst_offset % dst_c4size.x; dst_offset /= dst_c4size.x;\n" +" int h=dst_offset % dst_c4size.y; dst_offset /= dst_c4size.y;\n" +" int c=dst_offset % dst_c4size.z;\n" +" int b=dst_offset/dst_c4size.z;\n" +" int c4_size=(dst_c4size.z+3)/4;\n" +" dst_offsetC4=(((b*c4_size+(c/4))*dst_c4size.y+h)*dst_c4size.x+w)*4+(c % 4);\n" +"#endif\n" +" }\n" +" if(offset.x >= 0){\n" +" if(offset.y >= 0 && offset.y1\n" +" __local COMPUTE_FLOAT2 sum[WORK_GROUP_SIZE];\n" +"#endif\n" +"#if SLM_DIV_FACTOR>1\n" +" for (int icb=feature_sub_block*IC_BLOCKS/SLM_DIV_FACTOR; icb<(feature_sub_block+1)*IC_BLOCKS/SLM_DIV_FACTOR; icb++) {\n" +"#else\n" +" for (int icb=0; icb= input_height)\n" +" continue;\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" {\n" +" int xb=0;\n" +" for (; xb+8 <= INPUT_LINE_SIZE; xb += 8) {\n" +" COMPUTE_FLOAT8 tmp=CONVERT_COMPUTE_FLOAT8(GROUP_READ8(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" line_cache[xb+4]=tmp[4];\n" +" line_cache[xb+5]=tmp[5];\n" +" line_cache[xb+6]=tmp[6];\n" +" line_cache[xb+7]=tmp[7];\n" +" }\n" +" for (; xb+4 <= INPUT_LINE_SIZE; xb += 4) {\n" +" COMPUTE_FLOAT4 tmp=CONVERT_COMPUTE_FLOAT4(GROUP_READ4(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" }\n" +" for (; xb1\n" +" sum[lid1]=dst;\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" if (feature_sub_block == 0) {\n" +" __attribute__((opencl_unroll_hint)) for(int i=1; i= output_channel) {\n" +" for (int i=0; i<2 && (x+i)1\n" +" }\n" +"#endif\n" +"}\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void conv_2d_buf_subgroup_c16_c4_b4(\n" +" __global FLOAT* input,\n" +" __global FLOAT* output,\n" +" __global FLOAT* weights,\n" +" __global FLOAT* biases,\n" +" __private const int pad_width,\n" +" __private const int pad_height,\n" +" __private const int input_width,\n" +" __private const int input_height,\n" +" __private const int output_width,\n" +" __private const int output_height,\n" +" __private const int output_channel,\n" +" __private const int x_blocks,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right\n" +") {\n" +" const int sglid=get_sub_group_local_id();\n" +" const int b=(uint)get_global_id(2);\n" +" const int xy=get_global_id(0);\n" +" const int x=(xy % x_blocks) << 2;\n" +" const int y=(xy/x_blocks);\n" +" const int lid1=(int)get_local_id(1);\n" +" const int feature_per_wg=(int)get_local_size(1)/SLM_DIV_FACTOR;\n" +" const int feature_sub_block=lid1/feature_per_wg;\n" +" const int feature_block=(int)get_group_id(1);\n" +" const int input_x=x*STRIDE_WIDTH-pad_width;\n" +" const int input_y=y*STRIDE_HEIGHT-pad_height;\n" +" const uint input_x_pitch=16;\n" +" const uint input_y_pitch=input_x_pitch*(input_pad_left+input_width+input_pad_right);\n" +" const uint input_fs_pitch=input_y_pitch*(input_height);\n" +" const uint input_b_pitch=input_fs_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint input_offset=b*input_b_pitch +\n" +" input_y*input_y_pitch +\n" +" (input_x+input_pad_left)*input_x_pitch;\n" +" const uint output_x_pitch=4;\n" +" const uint output_y_pitch=output_x_pitch*output_width;\n" +" const uint output_fs_pitch=output_y_pitch*output_height;\n" +" const uint output_b_pitch=output_fs_pitch*((output_channel+3)/4);\n" +" const uint output_offset=b*output_b_pitch +\n" +" (feature_block << 2)*output_fs_pitch +\n" +" y*output_y_pitch +\n" +" x*output_x_pitch;\n" +" const uint filter_isv_pitch=16;\n" +" const uint filter_x_pitch=16*16;\n" +" const uint filter_y_pitch=filter_x_pitch*FILTER_WIDTH;\n" +" const uint filter_is_pitch=filter_y_pitch*FILTER_HEIGHT;\n" +" const uint filter_os_pitch=filter_is_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint filter_offset=feature_block*filter_os_pitch;\n" +"#if SLM_DIV_FACTOR == 1\n" +" COMPUTE_FLOAT4 dst=(COMPUTE_FLOAT4)((GROUP_READ(biases,feature_block*16)));\n" +"#else\n" +" COMPUTE_FLOAT4 dst;\n" +" if (feature_sub_block == 0) {\n" +" dst=(COMPUTE_FLOAT4)((GROUP_READ(biases,feature_block*16)));\n" +" } else {\n" +" dst=(COMPUTE_FLOAT4)0;\n" +" }\n" +"#endif \n" +"#if SLM_DIV_FACTOR>1\n" +" __local COMPUTE_FLOAT4 sum[WORK_GROUP_SIZE];\n" +"#endif\n" +"#if SLM_DIV_FACTOR>1\n" +" for (int icb=feature_sub_block*IC_BLOCKS/SLM_DIV_FACTOR; icb<(feature_sub_block+1)*IC_BLOCKS/SLM_DIV_FACTOR; icb++) {\n" +"#else\n" +" for (int icb=0; icb= input_height)\n" +" continue;\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" {\n" +" int xb=0;\n" +" for (; xb+8 <= INPUT_LINE_SIZE; xb += 8) {\n" +" COMPUTE_FLOAT8 tmp=CONVERT_COMPUTE_FLOAT8(GROUP_READ8(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" line_cache[xb+4]=tmp[4];\n" +" line_cache[xb+5]=tmp[5];\n" +" line_cache[xb+6]=tmp[6];\n" +" line_cache[xb+7]=tmp[7];\n" +" }\n" +" for (; xb+4 <= INPUT_LINE_SIZE; xb += 4) {\n" +" COMPUTE_FLOAT4 tmp=CONVERT_COMPUTE_FLOAT4(GROUP_READ4(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" }\n" +" for (; xb1\n" +" sum[lid1]=dst;\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" if (feature_sub_block == 0) {\n" +" __attribute__((opencl_unroll_hint)) for(int i=1; i= output_channel) {\n" +" for (int i=0; i<4 && (x+i)1\n" +" }\n" +"#endif\n" +"}\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void conv_2d_buf_subgroup_c16_c4_b8(\n" +" __global FLOAT* input,\n" +" __global FLOAT* output,\n" +" __global FLOAT* weights,\n" +" __global FLOAT* biases,\n" +" __private const int pad_width,\n" +" __private const int pad_height,\n" +" __private const int input_width,\n" +" __private const int input_height,\n" +" __private const int output_width,\n" +" __private const int output_height,\n" +" __private const int output_channel,\n" +" __private const int x_blocks,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right\n" +") {\n" +" const int sglid=get_sub_group_local_id();\n" +" const int b=(uint)get_global_id(2);\n" +" const int xy=get_global_id(0);\n" +" const int x=(xy % x_blocks) << 3;\n" +" const int y=(xy/x_blocks);\n" +" const int lid1=(int)get_local_id(1);\n" +" const int feature_per_wg=(int)get_local_size(1)/SLM_DIV_FACTOR;\n" +" const int feature_sub_block=lid1/feature_per_wg;\n" +" const int feature_block=(int)get_group_id(1);\n" +" const int input_x=x*STRIDE_WIDTH-pad_width;\n" +" const int input_y=y*STRIDE_HEIGHT-pad_height;\n" +" const uint input_x_pitch=16;\n" +" const uint input_y_pitch=input_x_pitch*(input_pad_left+input_width+input_pad_right);\n" +" const uint input_fs_pitch=input_y_pitch*(input_height);\n" +" const uint input_b_pitch=input_fs_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint input_offset=b*input_b_pitch +\n" +" input_y*input_y_pitch +\n" +" (input_x+input_pad_left)*input_x_pitch;\n" +" const uint output_x_pitch=4;\n" +" const uint output_y_pitch=output_x_pitch*output_width;\n" +" const uint output_fs_pitch=output_y_pitch*output_height;\n" +" const uint output_b_pitch=output_fs_pitch*((output_channel+3)/4);\n" +" const uint output_offset=b*output_b_pitch +\n" +" (feature_block << 2)*output_fs_pitch +\n" +" y*output_y_pitch +\n" +" x*output_x_pitch;\n" +" const uint filter_isv_pitch=16;\n" +" const uint filter_x_pitch=16*16;\n" +" const uint filter_y_pitch=filter_x_pitch*FILTER_WIDTH;\n" +" const uint filter_is_pitch=filter_y_pitch*FILTER_HEIGHT;\n" +" const uint filter_os_pitch=filter_is_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint filter_offset=feature_block*filter_os_pitch;\n" +"#if SLM_DIV_FACTOR == 1\n" +" COMPUTE_FLOAT8 dst=(COMPUTE_FLOAT8)(GROUP_READ(biases,feature_block*16));\n" +"#else\n" +" COMPUTE_FLOAT8 dst;\n" +" if (feature_sub_block == 0) {\n" +" dst=(COMPUTE_FLOAT8)(GROUP_READ(biases,feature_block*16));\n" +" } else {\n" +" dst=(COMPUTE_FLOAT8)0;\n" +" }\n" +"#endif \n" +"#if SLM_DIV_FACTOR>1\n" +" __local COMPUTE_FLOAT8 sum[WORK_GROUP_SIZE];\n" +"#endif\n" +"#if SLM_DIV_FACTOR>1\n" +" for (int icb=feature_sub_block*IC_BLOCKS/SLM_DIV_FACTOR; icb<(feature_sub_block+1)*IC_BLOCKS/SLM_DIV_FACTOR; icb++) {\n" +"#else\n" +" for (int icb=0; icb= input_height)\n" +" continue;\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" {\n" +" int xb=0;\n" +" for (; xb+8 <= INPUT_LINE_SIZE; xb += 8) {\n" +" COMPUTE_FLOAT8 tmp=CONVERT_COMPUTE_FLOAT8(GROUP_READ8(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" line_cache[xb+4]=tmp[4];\n" +" line_cache[xb+5]=tmp[5];\n" +" line_cache[xb+6]=tmp[6];\n" +" line_cache[xb+7]=tmp[7];\n" +" }\n" +" for (; xb+4 <= INPUT_LINE_SIZE; xb += 4) {\n" +" COMPUTE_FLOAT4 tmp=CONVERT_COMPUTE_FLOAT4(GROUP_READ4(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" }\n" +" for (; xb1\n" +" sum[lid1]=dst;\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" if (feature_sub_block == 0) {\n" +" __attribute__((opencl_unroll_hint)) for(int i=1; i= output_channel) {\n" +" for (int i=0; i<8 && (x+i)1\n" +" }\n" +"#endif\n" +"}\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void conv_2d_buf_subgroup_c16_c16_b2(\n" +" __global FLOAT* input,\n" +" __global FLOAT* output,\n" +" __global FLOAT* weights,\n" +" __global FLOAT* biases,\n" +" __private const int pad_width,\n" +" __private const int pad_height,\n" +" __private const int input_width,\n" +" __private const int input_height,\n" +" __private const int output_width,\n" +" __private const int output_height,\n" +" __private const int output_channel,\n" +" __private const int x_blocks,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right\n" +") {\n" +" const int sglid=get_sub_group_local_id();\n" +" const int b=(uint)get_global_id(2);\n" +" const int xy=get_global_id(0);\n" +" const int x=(xy % x_blocks) << 1;\n" +" const int y=(xy/x_blocks);\n" +" const int lid1=(int)get_local_id(1);\n" +" const int feature_per_wg=(int)get_local_size(1)/SLM_DIV_FACTOR;\n" +" const int feature_sub_block=lid1/feature_per_wg;\n" +" const int feature_block=(int)get_group_id(1);\n" +" const int input_x=x*STRIDE_WIDTH-pad_width;\n" +" const int input_y=y*STRIDE_HEIGHT-pad_height;\n" +" const uint input_x_pitch=16;\n" +" const uint input_y_pitch=input_x_pitch*(input_pad_left+input_width+input_pad_right);\n" +" const uint input_fs_pitch=input_y_pitch*(input_height);\n" +" const uint input_b_pitch=input_fs_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint input_offset=b*input_b_pitch +\n" +" input_y*input_y_pitch +\n" +" (input_x+input_pad_left)*input_x_pitch;\n" +" const uint output_x_pitch=16;\n" +" const uint output_y_pitch=output_x_pitch*(output_pad_left+output_width+output_pad_right);\n" +" const uint output_fs_pitch=output_y_pitch*output_height;\n" +" const uint output_b_pitch=output_fs_pitch*((output_channel+15)/16);\n" +" const uint output_offset=b*output_b_pitch +\n" +" feature_block*output_fs_pitch +\n" +" y*output_y_pitch +\n" +" (x+output_pad_left)*output_x_pitch;\n" +" const uint filter_isv_pitch=16;\n" +" const uint filter_x_pitch=16*16;\n" +" const uint filter_y_pitch=filter_x_pitch*FILTER_WIDTH;\n" +" const uint filter_is_pitch=filter_y_pitch*FILTER_HEIGHT;\n" +" const uint filter_os_pitch=filter_is_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint filter_offset=feature_block*filter_os_pitch;\n" +"#if SLM_DIV_FACTOR == 1\n" +" COMPUTE_FLOAT2 dst=(COMPUTE_FLOAT2)(GROUP_READ(biases,feature_block*16));\n" +"#else\n" +" COMPUTE_FLOAT2 dst;\n" +" if (feature_sub_block == 0) {\n" +" dst=(COMPUTE_FLOAT2)(GROUP_READ(biases,feature_block*16));\n" +" } else {\n" +" dst=(COMPUTE_FLOAT2)0;\n" +" }\n" +"#endif \n" +"#if SLM_DIV_FACTOR>1\n" +" __local COMPUTE_FLOAT2 sum[WORK_GROUP_SIZE];\n" +"#endif\n" +"#if SLM_DIV_FACTOR>1\n" +" for (int icb=feature_sub_block*IC_BLOCKS/SLM_DIV_FACTOR; icb<(feature_sub_block+1)*IC_BLOCKS/SLM_DIV_FACTOR; icb++) {\n" +"#else\n" +" for (int icb=0; icb= input_height)\n" +" continue;\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" {\n" +" int xb=0;\n" +" for (; xb+8 <= INPUT_LINE_SIZE; xb += 8) {\n" +" COMPUTE_FLOAT8 tmp=CONVERT_COMPUTE_FLOAT8(GROUP_READ8(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" line_cache[xb+4]=tmp[4];\n" +" line_cache[xb+5]=tmp[5];\n" +" line_cache[xb+6]=tmp[6];\n" +" line_cache[xb+7]=tmp[7];\n" +" }\n" +" for (; xb+4 <= INPUT_LINE_SIZE; xb += 4) {\n" +" COMPUTE_FLOAT4 tmp=CONVERT_COMPUTE_FLOAT4(GROUP_READ4(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" }\n" +" for (; xb1\n" +" sum[lid1]=dst;\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" if (feature_sub_block == 0) {\n" +" __attribute__((opencl_unroll_hint)) for(int i=1; i= output_channel) {\n" +" for (int i=0; i<2; i++) {\n" +" if ((feature_block*16+sglid1\n" +" }\n" +"#endif\n" +"}\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void conv_2d_buf_subgroup_c16_c16_b4(\n" +" __global FLOAT* input,\n" +" __global FLOAT* output,\n" +" __global FLOAT* weights,\n" +" __global FLOAT* biases,\n" +" __private const int pad_width,\n" +" __private const int pad_height,\n" +" __private const int input_width,\n" +" __private const int input_height,\n" +" __private const int output_width,\n" +" __private const int output_height,\n" +" __private const int output_channel,\n" +" __private const int x_blocks,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right\n" +") {\n" +" const int sglid=get_sub_group_local_id();\n" +" const int b=(uint)get_global_id(2);\n" +" const int xy=get_global_id(0);\n" +" const int x=(xy % x_blocks) << 2;\n" +" const int y=(xy/x_blocks);\n" +" const int lid1=(int)get_local_id(1);\n" +" const int feature_per_wg=(int)get_local_size(1)/SLM_DIV_FACTOR;\n" +" const int feature_sub_block=lid1/feature_per_wg;\n" +" const int feature_block=(int)get_group_id(1);\n" +" const int input_x=x*STRIDE_WIDTH-pad_width;\n" +" const int input_y=y*STRIDE_HEIGHT-pad_height;\n" +" const uint input_x_pitch=16;\n" +" const uint input_y_pitch=input_x_pitch*(input_pad_left+input_width+input_pad_right);\n" +" const uint input_fs_pitch=input_y_pitch*(input_height);\n" +" const uint input_b_pitch=input_fs_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint input_offset=b*input_b_pitch +\n" +" input_y*input_y_pitch +\n" +" (input_x+input_pad_left)*input_x_pitch;\n" +" const uint output_x_pitch=16;\n" +" const uint output_y_pitch=output_x_pitch*(output_pad_left+output_width+output_pad_right);\n" +" const uint output_fs_pitch=output_y_pitch*output_height;\n" +" const uint output_b_pitch=output_fs_pitch*((output_channel+15)/16);\n" +" const uint output_offset=b*output_b_pitch +\n" +" feature_block*output_fs_pitch +\n" +" y*output_y_pitch +\n" +" (x+output_pad_left)*output_x_pitch;\n" +" const uint filter_isv_pitch=16;\n" +" const uint filter_x_pitch=16*16;\n" +" const uint filter_y_pitch=filter_x_pitch*FILTER_WIDTH;\n" +" const uint filter_is_pitch=filter_y_pitch*FILTER_HEIGHT;\n" +" const uint filter_os_pitch=filter_is_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint filter_offset=feature_block*filter_os_pitch;\n" +"#if SLM_DIV_FACTOR == 1\n" +" COMPUTE_FLOAT4 dst=(COMPUTE_FLOAT4)(GROUP_READ(biases,feature_block*16));\n" +"#else\n" +" COMPUTE_FLOAT4 dst;\n" +" if (feature_sub_block == 0) {\n" +" dst=(COMPUTE_FLOAT4)(GROUP_READ(biases,feature_block*16));\n" +" } else {\n" +" dst=(COMPUTE_FLOAT4)0;\n" +" }\n" +"#endif \n" +"#if SLM_DIV_FACTOR>1\n" +" __local COMPUTE_FLOAT4 sum[WORK_GROUP_SIZE];\n" +"#endif\n" +"#if SLM_DIV_FACTOR>1\n" +" for (int icb=feature_sub_block*IC_BLOCKS/SLM_DIV_FACTOR; icb<(feature_sub_block+1)*IC_BLOCKS/SLM_DIV_FACTOR; icb++) {\n" +"#else\n" +" for (int icb=0; icb= input_height)\n" +" continue;\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" {\n" +" int xb=0;\n" +" for (; xb+8 <= INPUT_LINE_SIZE; xb += 8) {\n" +" COMPUTE_FLOAT8 tmp=CONVERT_COMPUTE_FLOAT8(GROUP_READ8(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" line_cache[xb+4]=tmp[4];\n" +" line_cache[xb+5]=tmp[5];\n" +" line_cache[xb+6]=tmp[6];\n" +" line_cache[xb+7]=tmp[7];\n" +" }\n" +" for (; xb+4 <= INPUT_LINE_SIZE; xb += 4) {\n" +" COMPUTE_FLOAT4 tmp=CONVERT_COMPUTE_FLOAT4(GROUP_READ4(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" }\n" +" for (; xb1\n" +" sum[lid1]=dst;\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" if (feature_sub_block == 0) {\n" +" __attribute__((opencl_unroll_hint)) for(int i=1; i= output_channel) {\n" +" for (int i=0; i<4; i++) {\n" +" if ((feature_block*16+sglid1\n" +" }\n" +"#endif\n" +"}\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void conv_2d_buf_subgroup_c16_c16_b8(\n" +" __global FLOAT* input,\n" +" __global FLOAT* output,\n" +" __global FLOAT* weights,\n" +" __global FLOAT* biases,\n" +" __private const int pad_width,\n" +" __private const int pad_height,\n" +" __private const int input_width,\n" +" __private const int input_height,\n" +" __private const int output_width,\n" +" __private const int output_height,\n" +" __private const int output_channel,\n" +" __private const int x_blocks,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right,\n" +" __private const int output_pad_left,\n" +" __private const int output_pad_right\n" +") {\n" +" const int sglid=get_sub_group_local_id();\n" +" const int b=(uint)get_global_id(2);\n" +" const int xy=get_global_id(0);\n" +" const int x=(xy % x_blocks) << 3;\n" +" const int y=(xy/x_blocks);\n" +" const int lid1=(int)get_local_id(1);\n" +" const int feature_per_wg=(int)get_local_size(1)/SLM_DIV_FACTOR;\n" +" const int feature_sub_block=lid1/feature_per_wg;\n" +" const int feature_block=(int)get_group_id(1);\n" +" const int input_x=x*STRIDE_WIDTH-pad_width;\n" +" const int input_y=y*STRIDE_HEIGHT-pad_height;\n" +" const uint input_x_pitch=16;\n" +" const uint input_y_pitch=input_x_pitch*(input_pad_left+input_width+input_pad_right);\n" +" const uint input_fs_pitch=input_y_pitch*(input_height);\n" +" const uint input_b_pitch=input_fs_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint input_offset=b*input_b_pitch +\n" +" input_y*input_y_pitch +\n" +" (input_x+input_pad_left)*input_x_pitch;\n" +" const uint output_x_pitch=16;\n" +" const uint output_y_pitch=output_x_pitch*(output_pad_left+output_width+output_pad_right);\n" +" const uint output_fs_pitch=output_y_pitch*output_height;\n" +" const uint output_b_pitch=output_fs_pitch*((output_channel+15)/16);\n" +" const uint output_offset=b*output_b_pitch +\n" +" feature_block*output_fs_pitch +\n" +" y*output_y_pitch +\n" +" (x+output_pad_left)*output_x_pitch;\n" +" const uint filter_isv_pitch=16;\n" +" const uint filter_x_pitch=16*16;\n" +" const uint filter_y_pitch=filter_x_pitch*FILTER_WIDTH;\n" +" const uint filter_is_pitch=filter_y_pitch*FILTER_HEIGHT;\n" +" const uint filter_os_pitch=filter_is_pitch*((INPUT_CHANNEL+15)/16);\n" +" const uint filter_offset=feature_block*filter_os_pitch;\n" +"#if SLM_DIV_FACTOR == 1\n" +" COMPUTE_FLOAT8 dst=(COMPUTE_FLOAT8)(GROUP_READ(biases,feature_block*16));\n" +"#else\n" +" COMPUTE_FLOAT8 dst;\n" +" if (feature_sub_block == 0) {\n" +" dst=(COMPUTE_FLOAT8)(GROUP_READ(biases,feature_block*16));\n" +" } else {\n" +" dst=(COMPUTE_FLOAT8)0;\n" +" }\n" +"#endif \n" +"#if SLM_DIV_FACTOR>1\n" +" __local COMPUTE_FLOAT8 sum[WORK_GROUP_SIZE];\n" +"#endif\n" +"#if SLM_DIV_FACTOR>1\n" +" for (int icb=feature_sub_block*IC_BLOCKS/SLM_DIV_FACTOR; icb<(feature_sub_block+1)*IC_BLOCKS/SLM_DIV_FACTOR; icb++) {\n" +"#else\n" +" for (int icb=0; icb= input_height)\n" +" continue;\n" +" FLOAT line_cache[INPUT_LINE_SIZE];\n" +" {\n" +" int xb=0;\n" +" for (; xb+8 <= INPUT_LINE_SIZE; xb += 8) {\n" +" COMPUTE_FLOAT8 tmp=CONVERT_COMPUTE_FLOAT8(GROUP_READ8(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" line_cache[xb+4]=tmp[4];\n" +" line_cache[xb+5]=tmp[5];\n" +" line_cache[xb+6]=tmp[6];\n" +" line_cache[xb+7]=tmp[7];\n" +" }\n" +" for (; xb+4 <= INPUT_LINE_SIZE; xb += 4) {\n" +" COMPUTE_FLOAT4 tmp=CONVERT_COMPUTE_FLOAT4(GROUP_READ4(input,input_offset +\n" +" icb*input_fs_pitch +\n" +" kh*DILATION_HEIGHT*input_y_pitch +\n" +" xb*input_x_pitch));\n" +" \n" +" line_cache[xb+0]=tmp[0];\n" +" line_cache[xb+1]=tmp[1];\n" +" line_cache[xb+2]=tmp[2];\n" +" line_cache[xb+3]=tmp[3];\n" +" }\n" +" for (; xb1\n" +" sum[lid1]=dst;\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" if (feature_sub_block == 0) {\n" +" __attribute__((opencl_unroll_hint)) for(int i=1; i= output_channel) {\n" +" for (int i=0; i<8; i++) {\n" +" if ((feature_block*16+sglid1\n" +" }\n" +"#endif\n" +"}\n" +; +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* input_transe_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__attribute__((intel_reqd_sub_group_size(16)))\n" +"__kernel void conv_transe_c4_c1(\n" +" int global_size_dim0,\n" +" int global_size_dim1,\n" +" int global_size_dim2,\n" +" __global FLOAT* input,\n" +" __global FLOAT* output,\n" +" __private const int input_width,\n" +" __private const int input_height,\n" +" __private const int input_channel,\n" +" __private const int channel_blocks,\n" +" __private const int input_pad_left,\n" +" __private const int input_pad_right)\n" +"{\n" +" int x=get_global_id(0);\n" +" int w=x % input_width;\n" +" int h=x/input_width;\n" +" int c=get_global_id(1);\n" +" int b=get_global_id(2);\n" +" int cout=c << 2;\n" +" if(x >= global_size_dim0 || c >= global_size_dim1 || b >= global_size_dim2)\n" +" return;\n" +" // Input offset calculations:\n" +" const uint input_x_pitch=4;\n" +" const uint input_y_pitch=input_x_pitch*input_width;\n" +" const uint input_f_pitch=input_y_pitch*input_height;\n" +" const uint input_b_pitch=input_f_pitch*channel_blocks;\n" +" const uint input_offset=b*input_b_pitch +\n" +" c*input_f_pitch +\n" +" h*input_y_pitch +\n" +" w*input_x_pitch;\n" +" // Output offset calculations:\n" +" const uint output_x_pitch=1;\n" +" const uint output_y_pitch=output_x_pitch*input_width;\n" +" const uint output_f_pitch=output_y_pitch*input_height;\n" +" const uint output_b_pitch=output_f_pitch*input_channel;\n" +" const uint output_offset=b*output_b_pitch +\n" +" cout*output_f_pitch+\n" +" h*output_y_pitch +\n" +" w*output_x_pitch;\n" +" \n" +" FLOAT4 value=vload4(0,input+input_offset);\n" +" for(int i=0; i<4 && cout+i> 2;\n" +" if(x >= global_size_dim0 || c >= global_size_dim1 || b >= global_size_dim2)\n" +" return;\n" +" \n" +" // Input offset calculations:\n" +" const uint input_x_pitch=4;\n" +" const uint input_y_pitch=input_x_pitch*input_width;\n" +" const uint input_f_pitch=input_y_pitch*input_height;\n" +" const uint input_b_pitch=input_f_pitch*channel_blocks;\n" +" \n" +" const uint input_offset=b*input_b_pitch +\n" +" c*input_f_pitch +\n" +" h*input_y_pitch +\n" +" w*input_x_pitch;\n" +" \n" +" // Output offset calculations:\n" +" const uint output_x_pitch=16;\n" +" const uint output_y_pitch=output_x_pitch*(input_pad_left+input_width+input_pad_right);\n" +" const uint output_f_pitch=output_y_pitch*input_height;\n" +" const uint output_b_pitch=output_f_pitch*((input_channel+15)/16);\n" +" \n" +" const uint output_offset=b*output_b_pitch +\n" +" cout*output_f_pitch+\n" +" h*output_y_pitch +\n" +" (w+input_pad_left)*output_x_pitch+(c % 4)*4;\n" +" \n" +" FLOAT4 value=vload4(0,input+input_offset);\n" +" vstore4(value,0,output+output_offset);\n" +" if(w == 0){\n" +" uint pad_offset=b*output_b_pitch+cout*output_f_pitch+h*output_y_pitch+(c % 4)*4;\n" +" for(int i=0; i= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void reduct_width_buf(GLOBAL_SIZE_3_DIMS\n" +" __global const INPUT_TYPE* input,\n" +" __global OUTPUT_TYPE* output,\n" +" __private const int inputWidth,\n" +" __private const int inputHeight,\n" +" __private const int inputChannel,\n" +" __private const int inputBatch,\n" +" __private const int inputChannelBlock,\n" +" __private const int oututWidth,\n" +" __private const int outputHeight,\n" +" __private const int outputChannel,\n" +" __private const int outputChannelBlock\n" +" ) {\n" +" const int width_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int batch_idx=batch_channel_idx/outputChannelBlock;\n" +" const int channel_idx=batch_channel_idx % outputChannelBlock;\n" +" const int offset=((((batch_idx*inputChannelBlock)+channel_idx)*inputHeight+height_idx)*inputWidth+0)*4;\n" +" const int outputOffset=((((batch_idx*outputChannelBlock)+channel_idx)*outputHeight+height_idx)*oututWidth+0)*4;\n" +" INPUT_TYPE4 out=(INPUT_TYPE4)VALUE;\n" +" \n" +"#if LOCAL_SIZE>0\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE4 local sum[LOCAL_SIZE];\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid0\n" +" const int width_local_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_local_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int width_idx=get_group_id(0);\n" +" const int batch_idx=batch_channel_idx/outputChannelBlock;\n" +" const int channel_idx=batch_channel_idx % outputChannelBlock;\n" +" \n" +" const int offset=((((batch_idx*inputChannelBlock)+channel_idx)*inputHeight+0)*inputWidth+width_idx)*4;\n" +" const int outputOffset=((((batch_idx*outputChannelBlock)+channel_idx)*outputHeight+0)*oututWidth+width_idx)*4;\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE4 local sum[LOCAL_SIZE];\n" +" INPUT_TYPE4 out=(INPUT_TYPE4)VALUE;\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid0\n" +" const int width_local_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_idx=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(width_local_idx,height_idx,batch_idx);\n" +" const int width_idx=get_group_id(0);\n" +" \n" +" const int offset=((((batch_idx*inputChannelBlock)+0)*inputHeight+height_idx)*inputWidth+width_idx)*4;\n" +" const int outputOffset=((((batch_idx*outputChannelBlock)+0)*outputHeight+height_idx)*oututWidth+width_idx)*4;\n" +" int remain=inputChannel-(inputChannelBlock-1)*4;\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE local sum[LOCAL_SIZE];\n" +" INPUT_TYPE4 out=(INPUT_TYPE4)VALUE;\n" +" INPUT_TYPE4 in;\n" +" INPUT_TYPE *inPtr=(INPUT_TYPE*)∈\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid0\n" +" const int width_local_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_idx=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(width_local_idx,height_idx,batch_idx);\n" +" const int width_idx=get_group_id(0);\n" +" \n" +" const int offset=((((batch_idx*inputChannelBlock)+0)*inputHeight+height_idx)*inputWidth+width_idx)*4;\n" +" const int outputOffset=((batch_idx*outputHeight+height_idx)*oututWidth+width_idx);\n" +" int remain=inputChannel-(inputChannelBlock-1)*4;\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE local sum[LOCAL_SIZE];\n" +" INPUT_TYPE4 out=(INPUT_TYPE4)VALUE;\n" +" INPUT_TYPE4 in;\n" +" INPUT_TYPE *inPtr=(INPUT_TYPE*)∈\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid0\n" +" const int width_local_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_local_idx,height_idx,channel_idx);\n" +" const int width_idx=get_group_id(0);\n" +" \n" +" const int offset=((((0*inputChannelBlock)+channel_idx)*inputHeight+height_idx)*inputWidth+width_idx)*4;\n" +" const int outputOffset=((((0*outputChannelBlock)+channel_idx)*outputHeight+height_idx)*oututWidth+width_idx)*4;\n" +" int batchOffset=inputChannelBlock*inputHeight*inputWidth;\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE4 local sum[LOCAL_SIZE];\n" +" INPUT_TYPE4 out=(INPUT_TYPE4)VALUE;\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid local (matrix A)\n" +" #if SA == 1\n" +" GlobalToLocalA(agm,alm,kSizeM,tid,kwg);\n" +" #endif\n" +" // Loads data: off-chip --> local (matrix B)\n" +" #if SB == 1\n" +" GlobalToLocalB(bgm,blm,kSizeN,tid,kwg);\n" +" #endif\n" +" #if SA == 1 || SB == 1\n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" #endif\n" +" // Loops over all workitem tiles,unrolled by a factor KWI\n" +" for (int pwi=0; pwi private (matrix A)\n" +" #if GEMMK == 0 && SA == 1\n" +" apm[_mi]=LocalToPrivateA(alm,_mi,kg);\n" +" // Loads data: off-chip --> private (matrix A)\n" +" #elif GEMMK == 0 && SA == 0\n" +" apm[_mi]=GlobalToPrivateA(agm,_mi,kSizeM,idk,kwg);\n" +" #endif\n" +" }\n" +" // Loads matrix B (kernel 0) or matrix A (kernel 1)\n" +" #pragma unroll\n" +" for (int _ni=0; _ni private (matrix B)\n" +" #if SB == 1\n" +" bpm[_ni]=LocalToPrivateB(blm,_ni,kg);\n" +" // Loads data: off-chip --> private (matrix B)\n" +" #else\n" +" bpm[_ni]=GlobalToPrivateB(bgm,_ni,kSizeN,idk);\n" +" #endif\n" +" }\n" +" // Performs the accumulation (Cpm += Apm*Bpm)\n" +" #ifdef OUTPUTMN\n" +" #pragma unroll\n" +" for (int _mi=0; _mi= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void cast(GLOBAL_SIZE_3_DIMS\n" +" __read_only image2d_t input,\n" +" __write_only image2d_t output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channelBlock\n" +" ) {\n" +" const int width_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int batch_idx=batch_channel_idx/channelBlock;\n" +" const int channel_idx=batch_channel_idx % channelBlock;\n" +" \n" +"#ifdef TO_BOOL\n" +" int4 value=convert_int4(RI_DATA(input,SAMPLER,(int2)(channel_idx*width+width_idx,batch_idx*height+height_idx)));\n" +" value=value == (int4)0 ? (int4)0 : (int4)1;\n" +" WI_DATA(output,(int2)(channel_idx*width+width_idx,batch_idx*height+height_idx),CONVERT_OUTPUT_I4(value));\n" +"#else\n" +" INPUT_TYPE_I4 value=RI_DATA(input,SAMPLER,(int2)(channel_idx*width+width_idx,batch_idx*height+height_idx));\n" +" WI_DATA(output,(int2)(channel_idx*width+width_idx,batch_idx*height+height_idx),CONVERT_OUTPUT_I4(value));\n" +"#endif\n" +"}\n" +; +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* buffer_convert_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"// convert data from buffer(nhwc) to buffer(nc4hw4)\n" +"__kernel void nhwc_buffer_to_nc4hw4_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global const INPUT_TYPE *input_ptr,\n" +" __private const int height,\n" +" __private const int width,__private const int channels,\n" +" __global OUTPUT_TYPE *output) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_4_idx=(image_width_idx/width) << 2;\n" +" const int buffer_offset=((batch_idx*height+height_idx)*width+width_idx)*channels+channel_4_idx;\n" +" const int remain_channel=channels-channel_4_idx;\n" +" float4 values=convert_float4(vload4(0,input_ptr+buffer_offset));\n" +" if (remain_channel == 3) {\n" +" values.w=0;\n" +" } else if (remain_channel == 2) {\n" +" values.z=0;\n" +" values.w=0;\n" +" } else if (remain_channel == 1) {\n" +" values.y=0;\n" +" values.z=0;\n" +" values.w=0;\n" +" }\n" +" const int out_offset=(((batch_idx*((channels+3)/4)+channel_4_idx/4)*height+height_idx)*width+width_idx)*4;\n" +" vstore4(CONVERT_OUTPUT4(values),0,output+out_offset);\n" +"}\n" +"// convert data from buffer(nchw) to buffer(nc4hw4)\n" +"__kernel void nchw_buffer_to_nc4hw4_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global const INPUT_TYPE *input_ptr,\n" +" __private const int height,__private const int width,__private const int channels,\n" +" __global OUTPUT_TYPE *output) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_4_idx=image_width_idx/width << 2;\n" +" const int buffer_offset=((batch_idx*channels+channel_4_idx)*height+height_idx)*width+width_idx;\n" +" const int remain_channel=channels-channel_4_idx;\n" +" const int height_width_size=height*width;\n" +" float4 output_values=0;\n" +" if (remain_channel >= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(float)*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.y=(float)*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.z=(float)*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.w=(float)*(input_ptr+offset);\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(float)*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.y=(float)*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.z=(float)*(input_ptr+offset);\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(float)*(input_ptr+offset);\n" +" offset += height_width_size;\n" +" output_values.y=(float)*(input_ptr+offset);\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(float)*(input_ptr+offset);\n" +" }\n" +" const int out_offset=(((batch_idx*((channels+3)/4)+channel_4_idx/4)*height+height_idx)*width+width_idx)*4;\n" +" vstore4(CONVERT_OUTPUT4(output_values),0,output+out_offset);\n" +"}\n" +"__kernel void nchw_buffer_to_nchw_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global INPUT_TYPE *input_ptr,\n" +" __private const int height,__private const int width,__private const int channels,\n" +" __private const int input_pad_left,__private const int input_pad_right,\n" +" __private const int output_pad_left,__private const int output_pad_right,\n" +" __global OUTPUT_TYPE *output) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int src_width=width+input_pad_left+input_pad_right;\n" +" const int dst_width=width+output_pad_left+output_pad_right;\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_idx=image_width_idx/width;\n" +" const int in_offset=((batch_idx*channels+channel_idx)*height+height_idx)*src_width+width_idx+input_pad_left;\n" +" const int out_offset=((batch_idx*channels+channel_idx)*height+height_idx)*dst_width+width_idx+output_pad_left;\n" +" output[out_offset]=(OUTPUT_TYPE)input_ptr[in_offset];\n" +"}\n" +"// convert data from image(b h,ic/4 w ic4) to buffer(nhwc)\n" +"__kernel void nc4hw4_buffer_to_nhwc_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int height,__private const int width,\n" +" __private const int channels,\n" +" __global INPUT_TYPE *input_ptr) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" const int channel_4_idx=(image_width_idx/width) << 2;\n" +" const int buffer_offset=((batch_idx*height+height_idx)*width+width_idx)*channels+channel_4_idx;\n" +" const int in_offset=(((batch_idx*((channels+3)/4)+channel_4_idx/4)*height+height_idx)*width+width_idx)*4;\n" +" \n" +" float4 values=convert_float4(vload4(0,input_ptr+in_offset));\n" +" const int remain_channel=channels-channel_4_idx;\n" +" if (remain_channel >= 4) {\n" +" vstore4(CONVERT_OUTPUT4(values),0,output+buffer_offset);\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.z;\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset++;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" }\n" +"}\n" +"// convert data from buffer(nc4hw4) to buffer(nchw)\n" +"__kernel void nc4hw4_buffer_to_nchw_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global OUTPUT_TYPE *output,\n" +" __private const int height,__private const int width,\n" +" __private const int channels,\n" +" __global INPUT_TYPE *input_ptr) {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" \n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/height;\n" +" const int height_idx=image_height_idx % height;\n" +" const int width_idx=image_width_idx % width;\n" +" int channel_4_idx=(image_width_idx/width)*4;\n" +" int buffer_offset=((batch_idx*channels+channel_4_idx)*height+height_idx)*width+width_idx;\n" +" \n" +" const int in_offset=(((batch_idx*((channels+3)/4)+channel_4_idx/4)*height+height_idx)*width+width_idx)*4;\n" +" float4 values=convert_float4(vload4(0,input_ptr+in_offset));\n" +" const int height_width_size=height*width;\n" +" const int remain_channel=channels-channel_4_idx;\n" +" if (remain_channel >= 4) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.z;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.w;\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.z;\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" offset += height_width_size;\n" +" output[offset]=(OUTPUT_TYPE)values.y;\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output[offset]=(OUTPUT_TYPE)values.x;\n" +" }\n" +"}\n" +"__kernel void nc4hw4_buffer_to_nc4hw4_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global const INPUT_TYPE *input_ptr,\n" +" __private const int2 output_shape,\n" +" __private const int2 src_stride,\n" +" __private const int2 dst_stride,\n" +" __global OUTPUT_TYPE *output\n" +") {\n" +" int image_width_idx=get_global_id(0);\n" +" int image_height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int batch_idx=image_height_idx/output_shape.x;\n" +" const int height_idx=image_height_idx % output_shape.x;\n" +" const int width_idx=image_width_idx % output_shape.y;\n" +" const int channel_block_idx=image_width_idx/output_shape.y;\n" +" int2 src_bc_offset=src_stride*(int2)(batch_idx,channel_block_idx);\n" +" int2 dst_bc_offset=dst_stride*(int2)(batch_idx,channel_block_idx);\n" +" int src_buffer_offset =\n" +" (((src_bc_offset.x+src_bc_offset.y)*output_shape.x+height_idx)*output_shape.y+width_idx)*4;\n" +" int dst_buffer_offset =\n" +" (((dst_bc_offset.x+dst_bc_offset.y)*output_shape.x+height_idx)*output_shape.y+width_idx)*4;\n" +" \n" +" vstore4(CONVERT_OUTPUT4(vload4(0,input_ptr+src_buffer_offset)),0,output+dst_buffer_offset);\n" +"}\n" +"// convert kernel : from buffer(oihw) to image(oc/4 h w ,ic oc4)\n" +"__kernel void conv2d_filter_buffer_to_nc4hw4_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input_ptr,\n" +" __private const int output_channel,\n" +" __private const int2 kernel_shape,\n" +" __private const int ic_h_w_size,\n" +" __private const int height_width_size,\n" +" __global FLOAT *output) {\n" +" int image_width_idx=get_global_id(0); // ic\n" +" int image_height_idx=get_global_id(1); // oc/4 h w\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int input_channel_4_idx=image_width_idx;\n" +" const int output_channel_4_idx=(image_height_idx/height_width_size)*4;\n" +" const int height_width_idx=image_height_idx % height_width_size;\n" +" const int buffer_height_idx=height_width_idx/kernel_shape.y;\n" +" const int buffer_width_idx=height_width_idx % kernel_shape.y;\n" +" const int buffer_offset=output_channel_4_idx*ic_h_w_size+input_channel_4_idx*height_width_size +\n" +" buffer_height_idx*kernel_shape.y+buffer_width_idx;\n" +" FLOAT4 output_values=0;\n" +" if (output_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.w=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" const int out_offset=(image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*4;\n" +" vstore4(output_values,0,output+out_offset);\n" +"}\n" +"// convert kernel : from buffer(oihw) to image(oc/4 h w ,ic oc4)\n" +"__kernel void conv2d_filter_buffer_to_nc4hw4_buffer_floatin(GLOBAL_SIZE_2_DIMS\n" +" __global const float *input_ptr,\n" +" __private const int output_channel,\n" +" __private const int2 kernel_shape,\n" +" __private const int ic_h_w_size,\n" +" __private const int height_width_size,\n" +" __global FLOAT *output) {\n" +" int image_width_idx=get_global_id(0); // ic\n" +" int image_height_idx=get_global_id(1); // oc/4 h w\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" const int input_channel_4_idx=image_width_idx;\n" +" const int output_channel_4_idx=(image_height_idx/height_width_size)*4;\n" +" const int height_width_idx=image_height_idx % height_width_size;\n" +" const int buffer_height_idx=height_width_idx/kernel_shape.y;\n" +" const int buffer_width_idx=height_width_idx % kernel_shape.y;\n" +" const int buffer_offset=output_channel_4_idx*ic_h_w_size+input_channel_4_idx*height_width_size +\n" +" buffer_height_idx*kernel_shape.y+buffer_width_idx;\n" +" FLOAT4 output_values=0;\n" +" if (output_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.w=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += ic_h_w_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset=mad24(1,ic_h_w_size,offset);\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" const int out_offset=(image_width_idx*height_width_size*((output_channel+3)/4)+image_height_idx)*4;\n" +" vstore4(output_values,0,output+out_offset);\n" +"}\n" +"// convert kernel from buffer(mihw) to image(ic/4,ic4 h w m)\n" +"// but now dw only support m == 1\n" +"__kernel void dw_filter_buffer_to_nc4hw4_buffer(GLOBAL_SIZE_2_DIMS\n" +" __global const FLOAT *input_ptr,\n" +" __private const int4 kernel_shape,//[1,Cout,fh,fw]\n" +" __private const int height_width_size,\n" +" __global FLOAT *output) {\n" +" const int image_width_idx=get_global_id(0);//fh*fw\n" +" const int image_height_idx=get_global_id(1);//UP_DIV(Cout,4)\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" FLOAT4 output_values=0;\n" +" if (kernel_shape.x == 1) {\n" +" const int input_channel_4_idx=image_height_idx*4;\n" +" const int buffer_height_idx=image_width_idx/kernel_shape.w;\n" +" const int buffer_width_idx=image_width_idx % kernel_shape.w;\n" +" const int buffer_offset =\n" +" mad24(mad24(input_channel_4_idx,kernel_shape.z,buffer_height_idx),kernel_shape.w,buffer_width_idx);\n" +" //input [1,Cout,fh,fw]\n" +" //index:[0,input_channel_4_idx,buffer_height_idx,buffer_width_idx]\n" +" const int remain_channel=kernel_shape.y-input_channel_4_idx;\n" +" if (input_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.w=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" }\n" +" //output NC4HW4 [1,fw*fh,1,Cout/4]x oc4\n" +" //index: [0,image_width_idx,0,image_height_idx]\n" +" const int out_offset=(image_width_idx*((kernel_shape.y+3)/4)+image_height_idx)*4;\n" +" vstore4(output_values,0,output+out_offset);\n" +"}\n" +"__kernel void dw_filter_buffer_to_nc4hw4_buffer_floatin(GLOBAL_SIZE_2_DIMS\n" +" __global const float *input_ptr,\n" +" __private const int4 kernel_shape,//[1,Cout,fh,fw]\n" +" __private const int height_width_size,\n" +" __global FLOAT *output) {\n" +" const int image_width_idx=get_global_id(0);//fh*fw\n" +" const int image_height_idx=get_global_id(1);//UP_DIV(Cout,4)\n" +" DEAL_NON_UNIFORM_DIM2(image_width_idx,image_height_idx);\n" +" FLOAT4 output_values=0;\n" +" if (kernel_shape.x == 1) {\n" +" const int input_channel_4_idx=image_height_idx*4;\n" +" const int buffer_height_idx=image_width_idx/kernel_shape.w;\n" +" const int buffer_width_idx=image_width_idx % kernel_shape.w;\n" +" const int buffer_offset =\n" +" mad24(mad24(input_channel_4_idx,kernel_shape.z,buffer_height_idx),kernel_shape.w,buffer_width_idx);\n" +" //input [1,Cout,fh,fw]\n" +" //index:[0,input_channel_4_idx,buffer_height_idx,buffer_width_idx]\n" +" const int remain_channel=kernel_shape.y-input_channel_4_idx;\n" +" if (input_channel_4_idx= 4) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.w=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 3) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.z=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 2) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" offset += height_width_size;\n" +" output_values.y=(FLOAT)(*(input_ptr+offset));\n" +" } else if (remain_channel == 1) {\n" +" int offset=buffer_offset;\n" +" output_values.x=(FLOAT)(*(input_ptr+offset));\n" +" }\n" +" }\n" +" }\n" +" //output NC4HW4 [1,fw*fh,1,Cout/4]x oc4\n" +" //index: [0,image_width_idx,0,image_height_idx]\n" +" const int out_offset=(image_width_idx*((kernel_shape.y+3)/4)+image_height_idx)*4;\n" +" vstore4(output_values,0,output+out_offset);\n" +"}\n" +; +#endif +const char* matmul = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_2_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) ""if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { ""return; ""}\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void matmul(GLOBAL_SIZE_2_DIMS __read_only image2d_t input_a,\n" +" __read_only image2d_t input_b,\n" +" #ifdef BIAS\n" +" __read_only image2d_t input_c,\n" +" #endif\n" +" __write_only image2d_t output_c,__private const int channels,\n" +" __private const int channel_blocks) {\n" +" const int width_blocks_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(width_blocks_idx,height_idx);\n" +" FLOAT4 a;\n" +" FLOAT4 b0=0,b1=0,b2=0,b3=0;\n" +" #ifdef BIAS\n" +" FLOAT4 temp=RI_F(input_c,SAMPLER,(int2)(width_blocks_idx,0));\n" +" FLOAT result0=temp.x;\n" +" FLOAT result1=temp.y;\n" +" FLOAT result2=temp.z;\n" +" FLOAT result3=temp.w;\n" +" #else\n" +" FLOAT result0=0;\n" +" FLOAT result1=0;\n" +" FLOAT result2=0;\n" +" FLOAT result3=0;\n" +" #endif\n" +" for (short pos=0; pos= 1) ? v_zero : a3);\n" +" a2=((remain >= 2) ? v_zero : a2);\n" +" a1=((remain >= 3) ? v_zero : a1);\n" +" FLOAT4 a0_trans=(FLOAT4)(a0.x,a1.x,a2.x,a3.x);\n" +" FLOAT4 a1_trans=(FLOAT4)(a0.y,a1.y,a2.y,a3.y);\n" +" FLOAT4 a2_trans=(FLOAT4)(a0.z,a1.z,a2.z,a3.z);\n" +" FLOAT4 a3_trans=(FLOAT4)(a0.w,a1.w,a2.w,a3.w);\n" +" \n" +" FLOAT4 b0_trans=(FLOAT4)(b0.x,b1.x,b2.x,b3.x);\n" +" FLOAT4 b1_trans=(FLOAT4)(b0.y,b1.y,b2.y,b3.y);\n" +" FLOAT4 b2_trans=(FLOAT4)(b0.z,b1.z,b2.z,b3.z);\n" +" FLOAT4 b3_trans=(FLOAT4)(b0.w,b1.w,b2.w,b3.w);\n" +" //matmul\n" +" result0.x += dot(a0_trans,b0_trans);\n" +" result0.y += dot(a0_trans,b1_trans);\n" +" result0.z += dot(a0_trans,b2_trans);\n" +" result0.w += dot(a0_trans,b3_trans);\n" +" \n" +" result1.x += dot(a1_trans,b0_trans);\n" +" result1.y += dot(a1_trans,b1_trans);\n" +" result1.z += dot(a1_trans,b2_trans);\n" +" result1.w += dot(a1_trans,b3_trans);\n" +" \n" +" result2.x += dot(a2_trans,b0_trans);\n" +" result2.y += dot(a2_trans,b1_trans);\n" +" result2.z += dot(a2_trans,b2_trans);\n" +" result2.w += dot(a2_trans,b3_trans);\n" +" \n" +" result3.x += dot(a3_trans,b0_trans);\n" +" result3.y += dot(a3_trans,b1_trans);\n" +" result3.z += dot(a3_trans,b2_trans);\n" +" result3.w += dot(a3_trans,b3_trans);\n" +" }\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx),result0);\n" +" if(4*height_blocks_idx+1 >= height) return;\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx+1),result1);\n" +" if(4*height_blocks_idx+2 >= height) return;\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx+2),result2);\n" +" if(4*height_blocks_idx+3 >= height) return;\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx+3),result3);\n" +"}\n" +"__kernel void matmul_transA_transB(GLOBAL_SIZE_2_DIMS __read_only image2d_t input_a,\n" +" __read_only image2d_t input_b,\n" +" #ifdef BIAS\n" +" __read_only image2d_t input_c,\n" +" #endif\n" +" __write_only image2d_t output_c,\n" +" __private const int channels,\n" +" __private const int channel_blocks,\n" +" __private const int height) {\n" +" const int width_blocks_idx=get_global_id(0);\n" +" const int height_blocks_idx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(width_blocks_idx,height_blocks_idx);\n" +" FLOAT4 v_zero=(FLOAT4)((FLOAT)0.0);\n" +" #ifdef BIAS\n" +" FLOAT4 result0=RI_F(input_c,SAMPLER,(int2)(width_blocks_idx,0));\n" +" FLOAT4 result1=result0;\n" +" FLOAT4 result2=result0;\n" +" FLOAT4 result3=result0;\n" +" #else\n" +" FLOAT4 result0=0;\n" +" FLOAT4 result1=0;\n" +" FLOAT4 result2=0;\n" +" FLOAT4 result3=0;\n" +" #endif\n" +" for (short pos=0; pos= 1) ? v_zero : a3);\n" +" a2=((remain >= 2) ? v_zero : a2);\n" +" a1=((remain >= 3) ? v_zero : a1);\n" +" FLOAT4 a0_trans=(FLOAT4)(a0.x,a1.x,a2.x,a3.x);\n" +" FLOAT4 a1_trans=(FLOAT4)(a0.y,a1.y,a2.y,a3.y);\n" +" FLOAT4 a2_trans=(FLOAT4)(a0.z,a1.z,a2.z,a3.z);\n" +" FLOAT4 a3_trans=(FLOAT4)(a0.w,a1.w,a2.w,a3.w);\n" +" //matmul\n" +" result0.x += dot(a0_trans,b0);\n" +" result0.y += dot(a0_trans,b1);\n" +" result0.z += dot(a0_trans,b2);\n" +" result0.w += dot(a0_trans,b3);\n" +" \n" +" result1.x += dot(a1_trans,b0);\n" +" result1.y += dot(a1_trans,b1);\n" +" result1.z += dot(a1_trans,b2);\n" +" result1.w += dot(a1_trans,b3);\n" +" \n" +" result2.x += dot(a2_trans,b0);\n" +" result2.y += dot(a2_trans,b1);\n" +" result2.z += dot(a2_trans,b2);\n" +" result2.w += dot(a2_trans,b3);\n" +" \n" +" result3.x += dot(a3_trans,b0);\n" +" result3.y += dot(a3_trans,b1);\n" +" result3.z += dot(a3_trans,b2);\n" +" result3.w += dot(a3_trans,b3);\n" +" }\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx),result0);\n" +" if(4*height_blocks_idx+1 >= height) return;\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx+1),result1);\n" +" if(4*height_blocks_idx+2 >= height) return;\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx+2),result2);\n" +" if(4*height_blocks_idx+3 >= height) return;\n" +" WI_F(output_c,(int2)(width_blocks_idx,4*height_blocks_idx+3),result3);\n" +"}\n" +; +const char* binary = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define PI 3.141592653589f\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void binary(__private int global_dim0,__private int global_dim1,\n" +" __read_only image2d_t input0,__read_only image2d_t input1,\n" +" __write_only image2d_t output,\n" +" __private const int4 shape,//[N,H,W,C4]\n" +" __private const int2 isFull,\n" +" __private const int activationType) {\n" +" int2 pos=(int2)(get_global_id(0),get_global_id(1));//WC4,NH\n" +" \n" +" float4 in0,in1;\n" +" if (pos.x= dim.x && pos.y >= dim.y) {\n" +" return;\n" +" }\n" +" WI_DATA(output,pos,CONVERT_OUTPUT_I4(RI_DATA(input,SAMPLER,pos)));\n" +"}\n" +; +#ifndef MNN_OPENCL_BUFFER_CLOSED +const char* loop_buf = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define PI 3.141592653589f\n" +"#ifndef WGSW\n" +" #define WGSW 32 // work-group handle size W dimension\n" +"#endif\n" +"#ifndef WGSC\n" +" #define WGSC 32 // work-group handle size C dimension\n" +"#endif\n" +"#ifndef WGSH\n" +" #define WGSH 32 // work-group handle size H dimension\n" +"#endif\n" +"#ifndef TSW\n" +" #define TSW 8 // thread handle size W dimension\n" +"#endif\n" +"#ifndef TSC\n" +" #define TSC 8 // thread handle size C dimension\n" +"#endif\n" +"#ifndef TSH\n" +" #define TSH 8 // thread handle size H dimension\n" +"#endif\n" +"// [N C4 H 1 4] -> [N H C 1]\n" +"__kernel void tile_trans_3d_buf(__global INPUT_TYPE* input,\n" +" __global OUTPUT_TYPE* output,\n" +" __private const int widthPad,\n" +" __private const int heightPad,\n" +" __private const int channelPad,\n" +" __private const int batch,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel\n" +") {\n" +" int b=get_global_id(2);\n" +" \n" +" const int lidc=get_local_id(0);\n" +" const int lidh=get_local_id(1);\n" +" // group id\n" +" const int c=get_group_id(0)*WGSC;\n" +" const int h=get_group_id(1)*WGSH;\n" +" const int channel_4=(channel+3) >> 2;\n" +" int jc=lidc;\n" +" int ih=lidh;\n" +" \n" +" __local INPUT_TYPE4 localData[WGSH][WGSC/4];//h64c64\n" +" \n" +" #pragma unroll\n" +" for(int i=0; i= height || c+4*offset_c >= channel) ? (INPUT_TYPE4)0 : vload4(0,input+((b*channel_4+(c/4+offset_c))*height+(h+offset_h))*4);\n" +" }\n" +" }\n" +" \n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" \n" +" // C offset: [WGSC/TSC,TSC/4]\n" +" // H offset: [WGSH/TSH,TSH]\n" +" int oc_base=jc*TSC/4;\n" +" int oh_base=ih*TSH;\n" +" //#pragma unroll\n" +" for(int i=0; i [N C W H]\n" +"__kernel void tile_trans_4d_buf(__global INPUT_TYPE* input,\n" +" __global OUTPUT_TYPE* output,\n" +" __private const int widthPad,\n" +" __private const int heightPad,\n" +" __private const int channelPad,\n" +" __private const int batch,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel\n" +") {\n" +" int bc=get_global_id(2);\n" +" int b=bc % batch;\n" +" int c4=bc/batch;\n" +" int c=c4 << 2;\n" +" \n" +" const int lidw=get_local_id(0);\n" +" const int lidh=get_local_id(1);\n" +" // group id\n" +" const int w=get_group_id(0)*WGSW;\n" +" const int h=get_group_id(1)*WGSH;\n" +" const int channel_4=(channel+3) >> 2;\n" +" int jw=lidw;\n" +" int ih=lidh;\n" +" \n" +" __local INPUT_TYPE4 localData[WGSH][WGSW];//w32h32c4\n" +" \n" +" #pragma unroll\n" +" for(int i=0; i= height || offset_w >= width) ? (INPUT_TYPE4)0 : vload4(0,input+(((b*channel_4+c4)*height+offset_h)*width+offset_w)*4);\n" +" }\n" +" }\n" +" \n" +" barrier(CLK_LOCAL_MEM_FENCE);\n" +" \n" +" // c4w32h32\n" +" int oh=ih*TSH >> 4;\n" +" int mh=ih & (16/TSH-1);\n" +" // TSW offset: [TSH/4,TSW/4,16/TSH]\n" +" int ow_base=jw*TSW;\n" +" int oh_offset=oh << 4;\n" +" //#pragma unroll\n" +" for(int i=0; i= width || h >= height || c >= channel);\n" +"#ifdef MNN_NHWC\n" +" #if defined(DIMENSION_3) && defined(TRANSPOSE)\n" +" // [N,W,H,1]\n" +" const int c_dst_pitch=1;\n" +" const int y_dst_pitch=c_dst_pitch*channelPad;\n" +" const int x_dst_pitch=y_dst_pitch*heightPad;\n" +" const int b_dst_pitch=x_dst_pitch*widthPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" #elif defined(DIMENSION_4) && defined(TRANSPOSE)\n" +" // [N,H,C,W]\n" +" const int x_dst_pitch=1;\n" +" const int c_dst_pitch=x_dst_pitch*widthPad;\n" +" const int y_dst_pitch=c_dst_pitch*channelPad;\n" +" const int b_dst_pitch=y_dst_pitch*heightPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" #elif defined(DIMENSION_3)\n" +" // [N,H,W,1]\n" +" const int c_dst_pitch=1;\n" +" const int x_dst_pitch=c_dst_pitch*channelPad;\n" +" const int y_dst_pitch=x_dst_pitch*widthPad;\n" +" const int b_dst_pitch=y_dst_pitch*heightPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" #else\n" +" // [N,H,W,C]\n" +" const int c_dst_pitch=1;\n" +" const int x_dst_pitch=c_dst_pitch*channelPad;\n" +" const int y_dst_pitch=x_dst_pitch*widthPad;\n" +" const int b_dst_pitch=y_dst_pitch*heightPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" #endif\n" +"#else\n" +" #if defined(DIMENSION_3) && defined(TRANSPOSE)\n" +" // [N,H,C,1]\n" +" const int x_dst_pitch=1;\n" +" const int c_dst_pitch=x_dst_pitch*widthPad;\n" +" const int y_dst_pitch=c_dst_pitch*channelPad;\n" +" const int b_dst_pitch=y_dst_pitch*heightPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" \n" +" #elif defined(DIMENSION_4) && defined(TRANSPOSE)\n" +" // [N,C,W,H]\n" +" const int y_dst_pitch=1;\n" +" const int x_dst_pitch=y_dst_pitch*heightPad;\n" +" const int c_dst_pitch=x_dst_pitch*widthPad;\n" +" const int b_dst_pitch=c_dst_pitch*channelPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" #elif defined(DIMENSION_3)\n" +" // [N,C,H,1]\n" +" const int x_dst_pitch=1;\n" +" const int y_dst_pitch=x_dst_pitch*widthPad;\n" +" const int c_dst_pitch=y_dst_pitch*heightPad;\n" +" const int b_dst_pitch=c_dst_pitch*channelPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" #else\n" +" // [N,C,H,W]\n" +" const int x_dst_pitch=1;\n" +" const int y_dst_pitch=x_dst_pitch*widthPad;\n" +" const int c_dst_pitch=y_dst_pitch*heightPad;\n" +" const int b_dst_pitch=c_dst_pitch*channelPad;\n" +" OUTPUT_TYPE4 value=outBound ? (OUTPUT_TYPE4)0 : CONVERT_OUTPUT4(vload4(0,input+b*b_src_pitch+c_4*c_src_pitch+h*y_src_pitch+w*x_src_pitch));\n" +" #endif\n" +"#endif\n" +" __global OUTPUT_TYPE* dst_ptr=output+b*b_dst_pitch+c*c_dst_pitch+h*y_dst_pitch+w*x_dst_pitch;\n" +" dst_ptr[0]=value.x;\n" +" if(c+1 >= channel)return;\n" +" dst_ptr[c_dst_pitch]=value.y;\n" +" if(c+2 >= channel)return;\n" +" dst_ptr[2*c_dst_pitch]=value.z;\n" +" if(c+3 >= channel)return;\n" +" dst_ptr[3*c_dst_pitch]=value.w;\n" +" }\n" +"}\n" +"__kernel void pack_buf(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __global INPUT_TYPE* input,__global OUTPUT_TYPE* output,\n" +" __private const int widthPad,\n" +" __private const int heightPad,\n" +" __private const int channelPad,\n" +" __private const int batch,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel){\n" +" int3 pos=(int3)(get_global_id(0),get_global_id(1),get_global_id(2));\n" +" if (pos.x= width || h >= height || c >= channel) {\n" +" return;\n" +" }\n" +" const int x_dst_pitch=4;\n" +" const int y_dst_pitch=x_dst_pitch*width;\n" +" const int c_dst_pitch=y_dst_pitch*height;\n" +" const int b_dst_pitch=c_dst_pitch*((channel+3)/4);\n" +"#ifdef MNN_NHWC\n" +" #if defined(TRANSPOSE) && defined(DIMENSION_3)\n" +" // [N,W,H,1]\n" +" const int c_src_pitch=1;\n" +" const int y_src_pitch=c_src_pitch;\n" +" const int x_src_pitch=y_src_pitch*heightPad;\n" +" const int b_src_pitch=x_src_pitch*widthPad;\n" +" #elif defined(TRANSPOSE) && defined(DIMENSION_4)\n" +" // [N,H,C,W]\n" +" const int x_src_pitch=1;\n" +" const int c_src_pitch=x_src_pitch*widthPad;\n" +" const int y_src_pitch=c_src_pitch*channelPad;\n" +" const int b_src_pitch=y_src_pitch*heightPad;\n" +" #else\n" +" // [N,H,W,C]\n" +" const int c_src_pitch=1;\n" +" const int x_src_pitch=c_src_pitch*channelPad;\n" +" const int y_src_pitch=x_src_pitch*widthPad;\n" +" const int b_src_pitch=y_src_pitch*heightPad;\n" +" #endif\n" +"#else\n" +" #if defined(TRANSPOSE) && defined(DIMENSION_3)\n" +" // dst:[N,C,H,1] -> src:[N,H,C,1]\n" +" const int x_src_pitch=1;\n" +" const int c_src_pitch=x_src_pitch*widthPad;\n" +" const int y_src_pitch=c_src_pitch*channelPad;\n" +" const int b_src_pitch=y_src_pitch*heightPad;\n" +" #elif defined(TRANSPOSE) && defined(DIMENSION_4)\n" +" // dst:[N,C,H,W] -> src:[N,C,W,H]\n" +" const int y_src_pitch=1;\n" +" const int x_src_pitch=y_src_pitch*heightPad;\n" +" const int c_src_pitch=x_src_pitch*widthPad;\n" +" const int b_src_pitch=c_src_pitch*channelPad;\n" +" #else\n" +" // [N,C,H,W]\n" +" const int x_src_pitch=1;\n" +" const int y_src_pitch=x_src_pitch*widthPad;\n" +" const int c_src_pitch=y_src_pitch*heightPad;\n" +" const int b_src_pitch=c_src_pitch*channelPad;\n" +" #endif\n" +"#endif\n" +" __global INPUT_TYPE* src_ptr=input+b*b_src_pitch+c*c_src_pitch+h*y_src_pitch+w*x_src_pitch;\n" +" OUTPUT_TYPE4 value=(OUTPUT_TYPE4)0;\n" +" OUTPUT_TYPE *value_ptr=(OUTPUT_TYPE*)&value;\n" +" for(int i=0; i<4 && (i+c= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"#define MIN_VALUE -FLT_MAX\n" +"// Supported data type: half/float\n" +"__kernel void roi_pooling(GLOBAL_SIZE_3_DIMS __read_only image2d_t input,__read_only image2d_t roi,\n" +" __private const int in_height,__private const int in_width,__private const int in_batch,\n" +" __private const int out_height,__private const int out_width,__private const float spatial_scale,\n" +" __write_only image2d_t output) {\n" +" const int out_channel_idx=get_global_id(0);\n" +" const int out_width_idx=get_global_id(1);\n" +" const int out_hb_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(out_channel_idx,out_width_idx,out_hb_idx);\n" +" const int roi_batch_idx=out_hb_idx/out_height;\n" +" const int out_height_idx=out_hb_idx % out_height;\n" +"#if defined ROI_C1H1W5\n" +" FLOAT4 roi_0=RI_F(roi,SAMPLER,(int2)(0,roi_batch_idx));\n" +" int input_batch=roi_0.x;\n" +" if(input_batch >= in_batch){\n" +" return;\n" +" }\n" +" FLOAT4 roi_1=RI_F(roi,SAMPLER,(int2)(1,roi_batch_idx));\n" +" FLOAT4 roi_2=RI_F(roi,SAMPLER,(int2)(2,roi_batch_idx));\n" +" FLOAT4 roi_3=RI_F(roi,SAMPLER,(int2)(3,roi_batch_idx));\n" +" FLOAT4 roi_4=RI_F(roi,SAMPLER,(int2)(4,roi_batch_idx));\n" +" int x1=round(roi_1.x*spatial_scale);\n" +" int y1=round(roi_2.x*spatial_scale);\n" +" int x2=round(roi_3.x*spatial_scale);\n" +" int y2=round(roi_4.x*spatial_scale);\n" +"#elif defined ROI_C5H1W1\n" +" FLOAT4 roi_0=RI_F(roi,SAMPLER,(int2)(0,roi_batch_idx));\n" +" int input_batch=roi_0.x;\n" +" if(input_batch >= in_batch){\n" +" return;\n" +" }\n" +" FLOAT4 roi_1=RI_F(roi,SAMPLER,(int2)(1,roi_batch_idx));\n" +" int x1=round(roi_0.y*spatial_scale);\n" +" int y1=round(roi_0.z*spatial_scale);\n" +" int x2=round(roi_0.w*spatial_scale);\n" +" int y2=round(roi_1.x*spatial_scale);\n" +"#else\n" +" const int roi_batch_offset=roi_batch_idx*5;\n" +" FLOAT4 roi_0=RI_F(roi,SAMPLER,(int2)(0,roi_batch_offset));\n" +" int input_batch=roi_0.x;\n" +" if(input_batch >= in_batch){\n" +" return;\n" +" }\n" +" FLOAT4 roi_1=RI_F(roi,SAMPLER,(int2)(0,roi_batch_offset+1));\n" +" FLOAT4 roi_2=RI_F(roi,SAMPLER,(int2)(0,roi_batch_offset+2));\n" +" FLOAT4 roi_3=RI_F(roi,SAMPLER,(int2)(0,roi_batch_offset+3));\n" +" FLOAT4 roi_4=RI_F(roi,SAMPLER,(int2)(0,roi_batch_offset+4));\n" +" int x1=round(roi_1.x*spatial_scale);\n" +" int y1=round(roi_2.x*spatial_scale);\n" +" int x2=round(roi_3.x*spatial_scale);\n" +" int y2=round(roi_4.x*spatial_scale);\n" +"#endif\n" +" int roiW=max(x2-x1+1,1);\n" +" int roiH=max(y2-y1+1,1);\n" +" float binSizeW=(float)roiW/(float)out_width;\n" +" float binSizeH=(float)roiH/(float)out_height;\n" +" int hStart=min(max(y1+(int)floor(out_height_idx*binSizeH),0),in_height);\n" +" int hEnd=min(max(y1+(int)ceil((out_height_idx+1)*binSizeH),0),in_height);\n" +" int hLen=hEnd-hStart;\n" +" int wStart=min(max(x1+(int)floor(out_width_idx*binSizeW),0),in_width);\n" +" int wEnd=min(max(x1+(int)ceil((out_width_idx+1)*binSizeW),0),in_width);\n" +" int wLen=wEnd-wStart;\n" +" const int pos=mad24(out_channel_idx,out_width,out_width_idx);\n" +" const FLOAT4 zero_vec=(FLOAT4)(0);\n" +" if (wLen <= 0 || hLen <= 0) {\n" +" WI_F(output,(int2)(pos,out_hb_idx),zero_vec);\n" +" return;\n" +" }\n" +" FLOAT4 res=(FLOAT4)(MIN_VALUE);\n" +" const int in_height_start=hStart;\n" +" const int in_width_start=wStart;\n" +" const int in_channel_offset=mul24(out_channel_idx,in_width);\n" +" const int in_height_offset=mul24(input_batch,in_height);\n" +" const int batch_idx=mul24(input_batch,in_height);\n" +" for (int height=0; height= inputShape.y)); "" inValue##i=RI_F(input,SAMPLER,(int2)(inOffset##i,inHeightIdx));\n" +"#define CALCULATE_OUTPUT(i) "" outValue##i = mad(inValue##i.x, weights0, outValue##i); "" outValue##i = mad(inValue##i.y, weights1, outValue##i); "" outValue##i = mad(inValue##i.z, weights2, outValue##i); "" outValue##i=mad(inValue##i.w,weights3,outValue##i);\n" +"#define GLOBAL_SIZE_2_DIMS __private const int global_size_dim0,__private const int global_size_dim1,\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"#define DEAL_NON_UNIFORM_DIM2(input1, input2) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1) { "" return; "" }\n" +"__kernel\n" +"#if SET_ATTRIBUTE\n" +"__attribute__((work_group_size_hint(16,16,1)))\n" +"#endif\n" +"void depthwise_conv2d_s1(GLOBAL_SIZE_2_DIMS __read_only image2d_t input,__read_only image2d_t filter,\n" +" #ifndef NO_BIAS\n" +" __read_only image2d_t bias,\n" +" #endif\n" +" __write_only image2d_t output,\n" +" __private const int2 inputShape,\n" +" __private const int inChannelBlocks,\n" +" __private const int2 outputShape,\n" +" __private const int2 filterShape,\n" +" __private const int2 paddingShape) {\n" +" const int outChannelWidthIdx=get_global_id(0);\n" +" const int outHeightBlockIdx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(outChannelWidthIdx,outHeightBlockIdx);\n" +" int ow4=(outputShape.y+3)/4;\n" +" const int outChannelBlockIdx=outChannelWidthIdx/ow4;\n" +" const int outWidthBlockidx=outChannelWidthIdx % ow4;\n" +" const int inChannelBlockIdx=outChannelBlockIdx;\n" +" #ifndef NO_BIAS\n" +" FLOAT4 outValue0=RI_F(bias,SAMPLER,(int2)(outChannelBlockIdx,0));\n" +" #else\n" +" FLOAT4 outValue0=(FLOAT4)(0.0f);\n" +" #endif\n" +" FLOAT4 outValue1=outValue0;\n" +" FLOAT4 outValue2=outValue0;\n" +" FLOAT4 outValue3=outValue0;\n" +" const int outWidthBlockidx4=outWidthBlockidx << 2;\n" +" const int inWidthOffset0=outWidthBlockidx4-paddingShape.y;\n" +" const int inWidthOffset1=inWidthOffset0+1;\n" +" const int inWidthOffset2=inWidthOffset0+2;\n" +" const int inWidthOffset3=inWidthOffset0+3;\n" +" int heightIdx=outHeightBlockIdx % outputShape.x-paddingShape.x;\n" +" const int outBatchIdx=mul24((outHeightBlockIdx/outputShape.x),inputShape.x);\n" +" const int inCurIdx=mul24(inChannelBlockIdx,inputShape.y);\n" +" const int inWidthIdx0=select(inCurIdx+inWidthOffset0,-1,(inWidthOffset0<0 || inWidthOffset0 >= inputShape.y));\n" +" const int inWidthIdx1=select(inCurIdx+inWidthOffset1,-1,(inWidthOffset1<0 || inWidthOffset1 >= inputShape.y));\n" +" const int inWidthIdx2=select(inCurIdx+inWidthOffset2,-1,(inWidthOffset2<0 || inWidthOffset2 >= inputShape.y));\n" +" FLOAT4 inValue0,inValue1,inValue2,inValue3;\n" +" for (int kh=0; kh= inputShape.x));\n" +" heightIdx++;\n" +" inValue1=RI_F(input,SAMPLER,(int2)(inWidthIdx0,inHeightIdx));\n" +" inValue2=RI_F(input,SAMPLER,(int2)(inWidthIdx1,inHeightIdx));\n" +" inValue3=RI_F(input,SAMPLER,(int2)(inWidthIdx2,inHeightIdx));\n" +" for (int kw=0; kw= inputShape.y));\n" +" inValue3=RI_F(input,SAMPLER,(int2)(inWidthIdx,inHeightIdx));\n" +" FLOAT4 weights=RI_F(filter,SAMPLER,(int2)(filterIdx,inChannelBlockIdx));\n" +" outValue0=mad(inValue0,weights,outValue0);\n" +" outValue1=mad(inValue1,weights,outValue1);\n" +" outValue2=mad(inValue2,weights,outValue2);\n" +" outValue3=mad(inValue3,weights,outValue3);\n" +" }\n" +" }\n" +"#ifdef RELU\n" +" outValue0=fmax(outValue0,(FLOAT4)0);\n" +" outValue1=fmax(outValue1,(FLOAT4)0);\n" +" outValue2=fmax(outValue2,(FLOAT4)0);\n" +" outValue3=fmax(outValue3,(FLOAT4)0);\n" +"#endif\n" +"#ifdef RELU6\n" +" outValue0=clamp(outValue0,(FLOAT4)0,(FLOAT4)6);\n" +" outValue1=clamp(outValue1,(FLOAT4)0,(FLOAT4)6);\n" +" outValue2=clamp(outValue2,(FLOAT4)0,(FLOAT4)6);\n" +" outValue3=clamp(outValue3,(FLOAT4)0,(FLOAT4)6);\n" +"#endif\n" +" const int remain=outputShape.y-outWidthBlockidx4;\n" +" int outWidthIdx=mul24(outChannelBlockIdx,outputShape.y)+outWidthBlockidx4;\n" +" if (remain >= 4) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightBlockIdx),outValue0);\n" +" WI_F(output,(int2)(outWidthIdx+1,outHeightBlockIdx),outValue1);\n" +" WI_F(output,(int2)(outWidthIdx+2,outHeightBlockIdx),outValue2);\n" +" WI_F(output,(int2)(outWidthIdx+3,outHeightBlockIdx),outValue3);\n" +" } else if (remain == 3) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightBlockIdx),outValue0);\n" +" WI_F(output,(int2)(outWidthIdx+1,outHeightBlockIdx),outValue1);\n" +" WI_F(output,(int2)(outWidthIdx+2,outHeightBlockIdx),outValue2);\n" +" } else if (remain == 2) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightBlockIdx),outValue0);\n" +" WI_F(output,(int2)(outWidthIdx+1,outHeightBlockIdx),outValue1);\n" +" } else if (remain == 1) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightBlockIdx),outValue0);\n" +" }\n" +"}\n" +"__kernel\n" +"#if SET_ATTRIBUTE\n" +"__attribute__((work_group_size_hint(16,16,1)))\n" +"#endif\n" +"void depthwise_conv2d(GLOBAL_SIZE_2_DIMS __read_only image2d_t input,__read_only image2d_t filter,\n" +" #ifndef NO_BIAS\n" +" __read_only image2d_t bias,\n" +" #endif\n" +" __write_only image2d_t output,\n" +" __private const int2 inputShape,\n" +" __private const int inChannelBlocks,__private const int2 outputShape,\n" +" __private const int2 filterShape,\n" +" __private const int2 paddingShape,\n" +" __private const int2 dilationShape,\n" +" __private const int2 strideShape) {\n" +" const int outChannelWidthIdx=get_global_id(0);\n" +" const int outHeightIdx=get_global_id(1);\n" +" DEAL_NON_UNIFORM_DIM2(outChannelWidthIdx,outHeightIdx);\n" +" int ow4=(outputShape.y+3)/4;\n" +" const int outChannelBlockIdx=outChannelWidthIdx/ow4;\n" +" const int outWidthBlockidx=outChannelWidthIdx % ow4;\n" +" const int inChannelBlockIdx=outChannelBlockIdx;\n" +" #ifndef NO_BIAS\n" +" FLOAT4 outValue0=RI_F(bias,SAMPLER,(int2)(outChannelBlockIdx,0));\n" +" #else\n" +" FLOAT4 outValue0=(FLOAT4)(0.0f);\n" +" #endif\n" +" FLOAT4 outValue1=outValue0;\n" +" FLOAT4 outValue2=outValue0;\n" +" FLOAT4 outValue3=outValue0;\n" +" const int inWidthOffset0=mad24(outWidthBlockidx,strideShape.y << 2,-paddingShape.y);\n" +" const int inWidthOffset1=inWidthOffset0+strideShape.y;\n" +" const int inWidthOffset2=inWidthOffset1+strideShape.y;\n" +" const int inWidthOffset3=inWidthOffset2+strideShape.y;\n" +" int heightIdx=mad24(outHeightIdx % outputShape.x,strideShape.x,-paddingShape.x);\n" +" const int outBatchIdx=mul24((outHeightIdx/outputShape.x),inputShape.x);\n" +" const int inCurIdx=mul24(inChannelBlockIdx,inputShape.y);\n" +" for (int kh=0; kh= inputShape.x));\n" +" heightIdx += dilationShape.x;\n" +" for (int kw=0; kw= 4) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightIdx),outValue0);\n" +" WI_F(output,(int2)(outWidthIdx+1,outHeightIdx),outValue1);\n" +" WI_F(output,(int2)(outWidthIdx+2,outHeightIdx),outValue2);\n" +" WI_F(output,(int2)(outWidthIdx+3,outHeightIdx),outValue3);\n" +" } else if (remain == 3) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightIdx),outValue0);\n" +" WI_F(output,(int2)(outWidthIdx+1,outHeightIdx),outValue1);\n" +" WI_F(output,(int2)(outWidthIdx+2,outHeightIdx),outValue2);\n" +" } else if (remain == 2) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightIdx),outValue0);\n" +" WI_F(output,(int2)(outWidthIdx+1,outHeightIdx),outValue1);\n" +" } else if (remain == 1) {\n" +" WI_F(output,(int2)(outWidthIdx,outHeightIdx),outValue0);\n" +" }\n" +"}\n" +; +const char* layernorm = +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void layernorm_w(__private int global_dim0,__private int global_dim1,__private int global_dim2,\n" +" __read_only image2d_t input,\n" +" __write_only image2d_t output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channel,\n" +"#ifdef GAMMA_BETA\n" +" __global const FLOAT *gamma,\n" +" __global const FLOAT *beta,\n" +"#endif\n" +" __private float epsilon){\n" +" int3 pos=(int3)(get_global_id(0),get_global_id(1),get_global_id(2));\n" +" float4 local sum[LOCAL_SIZE];\n" +" if (pos.x0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid0; i /= 2){\n" +" if (lid= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__kernel void cast_buf(GLOBAL_SIZE_3_DIMS\n" +" __global INPUT_TYPE* input,\n" +" __global OUTPUT_TYPE* output,\n" +" __private const int width,\n" +" __private const int height,\n" +" __private const int channelBlock\n" +" ) {\n" +" const int width_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int batch_idx=batch_channel_idx/channelBlock;\n" +" const int channel_idx=batch_channel_idx % channelBlock;\n" +" \n" +" const int inp_offset=((((batch_idx*channelBlock)+channel_idx)*height+height_idx)*width+width_idx)*4;\n" +"#ifdef TO_BOOL\n" +" int4 value=convert_int4(vload4(0,input+inp_offset));\n" +" value=value == (int4)0 ? (int4)0 : (int4)1;\n" +" vstore4(CONVERT_OUTPUT4(value),0,output+inp_offset);\n" +"#else\n" +" vstore4(CONVERT_OUTPUT4(vload4(0,input+inp_offset)),0,output+inp_offset);\n" +"#endif\n" +"}\n" +; +#endif +const char* reduction = +"// TODO: use INIT_SCALAR_VALUE,OPERATOR,FINAL_OPERATOR_ON_CHANNEL macro abstract and simplify code\n" +"// TODO: support reduce dims include batch\n" +"// TODO: support keep_dim=False\n" +"// TODO: fix channel reduce result re-pack problem\n" +"#ifdef MNN_SUPPORT_FP16\n" +"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n" +"#endif\n" +"#define GLOBAL_SIZE_3_DIMS "" __private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define GLOBAL_SIZE_2_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,\n" +"#define GLOBAL_SIZE_3_DIMS ""__private const int global_size_dim0,__private const int global_size_dim1,__private const int global_size_dim2,\n" +"#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) "" if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { "" return; "" }\n" +"__constant sampler_t SAMPLER=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n" +"__kernel void reduct_width(GLOBAL_SIZE_3_DIMS\n" +" __read_only image2d_t input,\n" +" __write_only image2d_t output,\n" +" __private const int inputWidth,\n" +" __private const int inputHeight,\n" +" __private const int inputChannel,\n" +" __private const int inputBatch,\n" +" __private const int inputChannelBlock,\n" +" __private const int oututWidth,\n" +" __private const int outputHeight,\n" +" __private const int outputChannel,\n" +" __private const int outputChannelBlock\n" +" ) {\n" +" const int width_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int batch_idx=batch_channel_idx/outputChannelBlock;\n" +" const int channel_idx=batch_channel_idx % outputChannelBlock;\n" +" const int bh=batch_idx*inputHeight+height_idx;\n" +" const int wc=channel_idx*inputWidth;\n" +" INPUT_TYPE_I4 out=(INPUT_TYPE_I4)VALUE;\n" +" \n" +"#if LOCAL_SIZE>0\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE_I4 local sum[LOCAL_SIZE];\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid0\n" +" const int width_local_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_local_idx,height_idx,batch_channel_idx);\n" +" \n" +" const int width_idx=get_group_id(0);\n" +" const int batch_idx=batch_channel_idx/outputChannelBlock;\n" +" const int channel_idx=batch_channel_idx % outputChannelBlock;\n" +" \n" +" const int bh=batch_idx*inputHeight;\n" +" const int wc=channel_idx*inputWidth+width_idx;\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE_I4 local sum[LOCAL_SIZE];\n" +" INPUT_TYPE_I4 out=(INPUT_TYPE_I4)VALUE;\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid0\n" +" const int width_local_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int batch_idx=get_global_id(2);\n" +" \n" +" DEAL_NON_UNIFORM_DIM3(width_local_idx,height_idx,batch_idx);\n" +" const int width_idx=get_group_id(0);\n" +" \n" +" const int bh=batch_idx*inputHeight+height_idx;\n" +" const int wc=width_idx;\n" +" int remain=inputChannel-(inputChannelBlock-1)*4;\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE_I local sum[LOCAL_SIZE];\n" +" INPUT_TYPE_I4 out=(INPUT_TYPE_I4)VALUE;\n" +" INPUT_TYPE_I4 in;\n" +" INPUT_TYPE_I *inPtr=(INPUT_TYPE_I*)∈\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid0\n" +" const int width_local_idx=get_global_id(0);\n" +" const int height_idx=get_global_id(1);\n" +" const int channel_idx=get_global_id(2);\n" +" DEAL_NON_UNIFORM_DIM3(width_local_idx,height_idx,channel_idx);\n" +" const int width_idx=get_group_id(0);\n" +" \n" +" const int bh=height_idx;\n" +" const int wc=channel_idx*inputWidth+width_idx;\n" +" int batchOffset=inputChannelBlock*inputHeight*inputWidth;\n" +" const int lid=get_local_id(0);\n" +" INPUT_TYPE_I4 local sum[LOCAL_SIZE];\n" +" INPUT_TYPE_I4 out=(INPUT_TYPE_I4)VALUE;\n" +" for(int i=lid; i0; i /= 2){\n" +" if (lid +#include +#include +#include +namespace MNN { +extern const char* conv_2d; +extern const char* deconv_2d; +extern const char* unary; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* grid_sample_buf; +#endif +extern const char* interp; +extern const char* select; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* range_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* self_attention_buf; +#endif +extern const char* performance; +extern const char* winogradTransformSource2_3_1; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* gemv_conv1x1_buf; +#endif +extern const char* raster; +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* conv_2d_c1_subgroup_buf; +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* matmul_local_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* conv_2d_int_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* interp_buf; +#endif +extern const char* scale; +extern const char* softmax; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* binary_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* gemm_quant_batch_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* raster_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* binary_subgroup_buf; +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* depthwise_conv2d_subgroup_buf; +#endif +#endif +extern const char* nearest; +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* pooling_subgroup_buf; +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* pooling_buf; +#endif +extern const char* winogradTransformSource2_5_1; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* unary_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* depthwise_conv2d_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* winogradTransform_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* winogradTransform_subgroup_buf; +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* splitgelu_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* select_buf; +#endif +extern const char* grid_sample; +extern const char* buffer_convert_quant; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* gemm_buf; +#endif +extern const char* copy_buffer_to_image2d; +extern const char* loop; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* argmax_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* buffer_convert_subgroup_buf; +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* attention_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* groupnorm_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* unary_subgroup_buf; +#endif +#endif +extern const char* gemm; +extern const char* depthwise_deconv2d; +extern const char* range; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* scale_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* matmul_buf; +#endif +extern const char* pooling; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* conv_2d_buf; +#endif +extern const char* buffer_to_image; +extern const char* winogradTransformDest2_3_1; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* layernorm_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* softmax_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* gather_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP +extern const char* conv_2d_c16_subgroup_buf; +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* input_transe_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* reduction_buf; +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* matmul_params_buf; +#endif +extern const char* cast; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* buffer_convert_buf; +#endif +extern const char* matmul; +extern const char* binary; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* loop_buf; +#endif +extern const char* roi_pooling; +extern const char* depthwise_conv2d; +extern const char* layernorm; +extern const char* winogradTransformDest2_5_1; +#ifndef MNN_OPENCL_BUFFER_CLOSED +extern const char* cast_buf; +#endif +extern const char* reduction; +const std::map OpenCLProgramMap = + { + { "conv_2d", conv_2d }, + { "deconv_2d", deconv_2d }, + { "unary", unary }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "grid_sample_buf", grid_sample_buf }, +#endif + { "interp", interp }, + { "select", select }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "range_buf", range_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "self_attention_buf", self_attention_buf }, +#endif + { "performance", performance }, + { "winogradTransformSource2_3_1", winogradTransformSource2_3_1 }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "gemv_conv1x1_buf", gemv_conv1x1_buf }, +#endif + { "raster", raster }, +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "conv_2d_c1_subgroup_buf", conv_2d_c1_subgroup_buf }, +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "matmul_local_buf", matmul_local_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "conv_2d_int_buf", conv_2d_int_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "interp_buf", interp_buf }, +#endif + { "scale", scale }, + { "softmax", softmax }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "binary_buf", binary_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "gemm_quant_batch_buf", gemm_quant_batch_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "raster_buf", raster_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "binary_subgroup_buf", binary_subgroup_buf }, +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "depthwise_conv2d_subgroup_buf", depthwise_conv2d_subgroup_buf }, +#endif +#endif + { "nearest", nearest }, +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "pooling_subgroup_buf", pooling_subgroup_buf }, +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "pooling_buf", pooling_buf }, +#endif + { "winogradTransformSource2_5_1", winogradTransformSource2_5_1 }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "unary_buf", unary_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "depthwise_conv2d_buf", depthwise_conv2d_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "winogradTransform_buf", winogradTransform_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "winogradTransform_subgroup_buf", winogradTransform_subgroup_buf }, +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "splitgelu_buf", splitgelu_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "select_buf", select_buf }, +#endif + { "grid_sample", grid_sample }, + { "buffer_convert_quant", buffer_convert_quant }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "gemm_buf", gemm_buf }, +#endif + { "copy_buffer_to_image2d", copy_buffer_to_image2d }, + { "loop", loop }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "argmax_buf", argmax_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "buffer_convert_subgroup_buf", buffer_convert_subgroup_buf }, +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "attention_buf", attention_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "groupnorm_buf", groupnorm_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "unary_subgroup_buf", unary_subgroup_buf }, +#endif +#endif + { "gemm", gemm }, + { "depthwise_deconv2d", depthwise_deconv2d }, + { "range", range }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "scale_buf", scale_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "matmul_buf", matmul_buf }, +#endif + { "pooling", pooling }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "conv_2d_buf", conv_2d_buf }, +#endif + { "buffer_to_image", buffer_to_image }, + { "winogradTransformDest2_3_1", winogradTransformDest2_3_1 }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "layernorm_buf", layernorm_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "softmax_buf", softmax_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "gather_buf", gather_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED +#ifdef MNN_SUPPORT_INTEL_SUBGROUP + { "conv_2d_c16_subgroup_buf", conv_2d_c16_subgroup_buf }, +#endif +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "input_transe_buf", input_transe_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "reduction_buf", reduction_buf }, +#endif +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "matmul_params_buf", matmul_params_buf }, +#endif + { "cast", cast }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "buffer_convert_buf", buffer_convert_buf }, +#endif + { "matmul", matmul }, + { "binary", binary }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "loop_buf", loop_buf }, +#endif + { "roi_pooling", roi_pooling }, + { "depthwise_conv2d", depthwise_conv2d }, + { "layernorm", layernorm }, + { "winogradTransformDest2_5_1", winogradTransformDest2_5_1 }, +#ifndef MNN_OPENCL_BUFFER_CLOSED + { "cast_buf", cast_buf }, +#endif + { "reduction", reduction }, +}; +} diff --git a/source/backend/opencl/execution/cl/self_attention_buf.cl b/source/backend/opencl/execution/cl/self_attention_buf.cl new file mode 100644 index 000000000..00529ef8d --- /dev/null +++ b/source/backend/opencl/execution/cl/self_attention_buf.cl @@ -0,0 +1,364 @@ +#ifdef MNN_SUPPORT_FP16 +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +#endif + +#define GLOBAL_SIZE_3_DIMS \ + __private const int global_size_dim0, __private const int global_size_dim1, __private const int global_size_dim2, + +#define DEAL_NON_UNIFORM_DIM3(input1, input2, input3) \ + if (input1 >= global_size_dim0 || input2 >= global_size_dim1 || input3 >= global_size_dim2) { \ + return; \ + } + +#define DEAL_HEAD_DIM_NOT_ALIGN \ + if(hd * 4 + 3 >= head_dim) {\ + temp_0.w = (FLOAT)0;\ + temp_1.w = (FLOAT)0;\ + temp_2.w = (FLOAT)0;\ + temp_3.w = (FLOAT)0;\ + }\ + if(hd * 4 + 2 >= head_dim) {\ + temp_0.z = (FLOAT)0;\ + temp_1.z = (FLOAT)0;\ + temp_2.z = (FLOAT)0;\ + temp_3.z = (FLOAT)0;\ + }\ + if(hd * 4 + 1 >= head_dim) {\ + temp_0.y = (FLOAT)0;\ + temp_1.y = (FLOAT)0;\ + temp_2.y = (FLOAT)0;\ + temp_3.y = (FLOAT)0;\ + } + +#define DEAL_SEQ_LEN_NOT_ALIGN \ + if(4 * sl + 3 >= seq_len) {\ + temp_3 = (FLOAT4)0;\ + }\ + if(4 * sl + 2 >= seq_len) {\ + temp_2 = (FLOAT4)0;\ + }\ + if(4 * sl + 1 >= seq_len) {\ + temp_1 = (FLOAT4)0;\ + } + +__kernel void split_transpose_qkv(GLOBAL_SIZE_3_DIMS + __global const FLOAT *input, // [Batch, seqLen/4, mNumHead * 3 * mHeadDim, 4] + __global FLOAT *output_q, // [Batch * mNumHead, head_dim_pack_k, seq_len_pack_mn / qSeqSplitNum] + __global FLOAT *output_k, // [Batch * mNumHead, head_dim_pack_k, seq_len_pack_mn] + __global FLOAT *output_v, // [Batch * mNumHead, ROUND_UP(seqLen, tile), head_dim_pack_mn] + __private const int seq_len_pack_mn, + __private const int seq_len_piece, + __private const int head_dim_pack_mn, + __private const int head_dim_pack_k, + __private const int seq_len, + __private const int head_num, + __private const int head_dim, + __private const int seq_index +) { + const int sl = get_global_id(0); // seqLen_4 + const int hd = get_global_id(1); // mHeadDim_4 + const int z = get_global_id(2); // Batch * mNumHead + DEAL_NON_UNIFORM_DIM3(sl, hd, z); + + const int b = z / head_num; + const int hn = z % head_num; + + const int seq_len_4 = (seq_len + 3) / 4; + const int offset_q = ((b * head_num + hn) * head_dim_pack_k + 4 * hd) * seq_len_piece + 4 * sl; + + if(seq_index > 0) { + // fill output_q only + if(sl * 4 >= seq_len || hd * 4 >= head_dim) { + if(hd * 4 < head_dim_pack_k) { + if(sl * 4 < seq_len_piece) { + vstore4((FLOAT4)0, 0, output_q + offset_q); + vstore4((FLOAT4)0, 0, output_q + offset_q + seq_len_piece); + vstore4((FLOAT4)0, 0, output_q + offset_q + seq_len_piece + seq_len_piece); + vstore4((FLOAT4)0, 0, output_q + offset_q + seq_len_piece + seq_len_piece + seq_len_piece); + } + } + return; + } + + const int offset_inp = (((b * seq_len_4 + seq_index * seq_len_piece / 4 + sl) * head_num + hn) * 3 * head_dim + 4 * hd) * 4; + + if(sl * 4 < seq_len_piece) { + FLOAT4 temp_0 = vload4(0, input + offset_inp); + FLOAT4 temp_1 = vload4(0, input + offset_inp + 4); + FLOAT4 temp_2 = vload4(0, input + offset_inp + 8); + FLOAT4 temp_3 = vload4(0, input + offset_inp + 12); + #ifdef HEADDIM_LEAVE + DEAL_HEAD_DIM_NOT_ALIGN + #endif + #ifdef SEQLEN_LEAVE + DEAL_SEQ_LEN_NOT_ALIGN + #endif + vstore4(temp_0, 0, output_q + offset_q); + vstore4(temp_1, 0, output_q + offset_q + seq_len_piece); + vstore4(temp_2, 0, output_q + offset_q + seq_len_piece + seq_len_piece); + vstore4(temp_3, 0, output_q + offset_q + seq_len_piece + seq_len_piece + seq_len_piece); + } + return; + } + const int offset_k = ((b * head_num + hn) * head_dim_pack_k + 4 * hd) * seq_len_pack_mn + 4 * sl; + + const int offset_v = ((b * head_num + hn) * seq_len_pack_mn + 4 * sl) * head_dim_pack_mn + 4 * hd; + if(sl * 4 >= seq_len || hd * 4 >= head_dim) { + if(hd * 4 < head_dim_pack_k) { + if(sl * 4 < seq_len_piece) { + vstore4((FLOAT4)0, 0, output_q + offset_q); + vstore4((FLOAT4)0, 0, output_q + offset_q + seq_len_piece); + vstore4((FLOAT4)0, 0, output_q + offset_q + seq_len_piece + seq_len_piece); + vstore4((FLOAT4)0, 0, output_q + offset_q + seq_len_piece + seq_len_piece + seq_len_piece); + } + vstore4((FLOAT4)0, 0, output_k + offset_k); + vstore4((FLOAT4)0, 0, output_k + offset_k + seq_len_pack_mn); + vstore4((FLOAT4)0, 0, output_k + offset_k + seq_len_pack_mn + seq_len_pack_mn); + vstore4((FLOAT4)0, 0, output_k + offset_k + seq_len_pack_mn + seq_len_pack_mn + seq_len_pack_mn); + } + vstore4((FLOAT4)0, 0, output_v + offset_v); + vstore4((FLOAT4)0, 0, output_v + offset_v + head_dim_pack_mn); + vstore4((FLOAT4)0, 0, output_v + offset_v + head_dim_pack_mn + head_dim_pack_mn); + vstore4((FLOAT4)0, 0, output_v + offset_v + head_dim_pack_mn + head_dim_pack_mn + head_dim_pack_mn); + + return; + } + + + const int offset_inp = (((b * seq_len_4 + sl) * head_num + hn) * 3 * head_dim + 4 * hd) * 4; + + if(sl * 4 < seq_len_piece) { + FLOAT4 temp_0 = vload4(0, input + offset_inp); + FLOAT4 temp_1 = vload4(0, input + offset_inp + 4); + FLOAT4 temp_2 = vload4(0, input + offset_inp + 8); + FLOAT4 temp_3 = vload4(0, input + offset_inp + 12); + #ifdef HEADDIM_LEAVE + DEAL_HEAD_DIM_NOT_ALIGN + #endif + #ifdef SEQLEN_LEAVE + DEAL_SEQ_LEN_NOT_ALIGN + #endif + vstore4(temp_0, 0, output_q + offset_q); + vstore4(temp_1, 0, output_q + offset_q + seq_len_piece); + vstore4(temp_2, 0, output_q + offset_q + seq_len_piece + seq_len_piece); + vstore4(temp_3, 0, output_q + offset_q + seq_len_piece + seq_len_piece + seq_len_piece); + } + + { + // K + FLOAT4 temp_0 = vload4(0, input + offset_inp + 4*head_dim); + FLOAT4 temp_1 = vload4(0, input + offset_inp + 4*head_dim + 4); + FLOAT4 temp_2 = vload4(0, input + offset_inp + 4*head_dim + 8); + FLOAT4 temp_3 = vload4(0, input + offset_inp + 4*head_dim + 12); + #ifdef HEADDIM_LEAVE + DEAL_HEAD_DIM_NOT_ALIGN + #endif + #ifdef SEQLEN_LEAVE + DEAL_SEQ_LEN_NOT_ALIGN + #endif + + vstore4(temp_0, 0, output_k + offset_k); + vstore4(temp_1, 0, output_k + offset_k + seq_len_pack_mn); + vstore4(temp_2, 0, output_k + offset_k + seq_len_pack_mn + seq_len_pack_mn); + vstore4(temp_3, 0, output_k + offset_k + seq_len_pack_mn + seq_len_pack_mn + seq_len_pack_mn); + + // V + temp_0 = vload4(0, input + offset_inp + 8 * head_dim); + temp_1 = vload4(0, input + offset_inp + 8 * head_dim + 4); + temp_2 = vload4(0, input + offset_inp + 8 * head_dim + 8); + temp_3 = vload4(0, input + offset_inp + 8 * head_dim + 12); + #ifdef HEADDIM_LEAVE + DEAL_HEAD_DIM_NOT_ALIGN + #endif + #ifdef SEQLEN_LEAVE + DEAL_SEQ_LEN_NOT_ALIGN + #endif + + vstore4((FLOAT4){temp_0.x, temp_1.x, temp_2.x, temp_3.x}, 0, output_v + offset_v); + vstore4((FLOAT4){temp_0.y, temp_1.y, temp_2.y, temp_3.y}, 0, output_v + offset_v + head_dim_pack_mn); + vstore4((FLOAT4){temp_0.z, temp_1.z, temp_2.z, temp_3.z}, 0, output_v + offset_v + head_dim_pack_mn + head_dim_pack_mn); + vstore4((FLOAT4){temp_0.w, temp_1.w, temp_2.w, temp_3.w}, 0, output_v + offset_v + head_dim_pack_mn + head_dim_pack_mn + head_dim_pack_mn); + } +} + + +#ifndef SOFTMAX_LOCAL_SIZE + #define SOFTMAX_LOCAL_SIZE 512 +#endif + +// [outside, axis, inside] -> reduce: inside +__kernel void softmax_inside(GLOBAL_SIZE_3_DIMS + __global const FLOAT *input, // [batch * mNumHead, ROUND_UP(seqLen, tile), ROUND_UP(seqLen, tile)] + __global FLOAT *output, + __private const int inside_len, + __private const int4 shape // [batch * mNumHead, ROUND_UP(seqLen, tile), ROUND_UP(seqLen, tile)] + ) { + const int inside = get_global_id(0); + const int axis = get_global_id(1); + const int outside = get_global_id(2); + DEAL_NON_UNIFORM_DIM3(inside, axis, outside); + + const int offset = (outside * shape.y + axis) * shape.z + 0; + + int lid = get_local_id(0); + float local sum[SOFTMAX_LOCAL_SIZE]; + + /*Compute Max */ + float maxValue = (float)(-FLT_MAX); + // clip to seq_len + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = fmax(sum[lid], sum[lid + i]); + barrier(CLK_LOCAL_MEM_FENCE); + } + maxValue = sum[0]; + + /*Compute Exp Sum*/ + float sumValue = 0; + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + sumValue = sum[0]; + + #ifdef OUTPUT_TRANSPOSE + const int out_offset = (outside * shape.z + 0) * shape.y + axis; + #endif + /*Compute Result */ + for (int i=lid; i [N Y X] +__kernel void trans_3d_buf(__global const FLOAT* input, + __global FLOAT* output, + __private const int batch, + __private const int width, + __private const int height +) { + int b = get_global_id(2); + + const int lidw = get_local_id(0); + const int lidh = get_local_id(1); + // group id + const int w = get_group_id(0) * WGSW; + const int h = get_group_id(1) * WGSH; + + int iw = lidw; + int jh = lidh; + + __local FLOAT4 localData[WGSW][WGSH/4];//w64h64 + + #pragma unroll + for(int i = 0; i < TSW; i++) { + int offset_w = i * WGSW / TSW + iw; + #pragma unroll + for(int j = 0; j < TSH / 4; j++) { + int offset_h = j * WGSH / TSH + jh; + // [TSW, WGSW / TSW] [TSH / 4, WGSH / TSH, 4] + localData[offset_w][offset_h] = vload4(0, input + ((b * width + (w+offset_w)) * height/4 + (h/4+offset_h)) * 4); + } + } + + barrier(CLK_LOCAL_MEM_FENCE); + + // H offset: [WGSH / TSH, TSH / 4, 4] + // W offset: [WGSW / TSW, TSW / 4, 4] + int oh_base = jh * TSH / 4; + int ow_base = iw * TSW / 4; + + //#pragma unroll + for(int j = 0; j < TSH / 4; j++) { + int oh = oh_base + j; + + //#pragma unroll + for(int i = 0; i < TSW / 4; i++) { + int ow = ow_base + i; + + FLOAT4 value_0 = (localData[4*ow][oh]); + FLOAT4 value_1 = (localData[4*ow+1][oh]); + FLOAT4 value_2 = (localData[4*ow+2][oh]); + FLOAT4 value_3 = (localData[4*ow+3][oh]); + vstore4((FLOAT4){value_0.x, value_1.x, value_2.x, value_3.x}, 0, output + ((b * height + h + 4*oh+0) * width + w + 4 * ow)); + vstore4((FLOAT4){value_0.y, value_1.y, value_2.y, value_3.y}, 0, output + ((b * height + h + 4*oh+1) * width + w + 4 * ow)); + vstore4((FLOAT4){value_0.z, value_1.z, value_2.z, value_3.z}, 0, output + ((b * height + h + 4*oh+2) * width + w + 4 * ow)); + vstore4((FLOAT4){value_0.w, value_1.w, value_2.w, value_3.w}, 0, output + ((b * height + h + 4*oh+3) * width + w + 4 * ow)); + } + } +} + + +__kernel void clip_transpose_qkv(GLOBAL_SIZE_3_DIMS + __global const FLOAT *input, // [Batch * mNumHead, ROUND_UP(mHeadDim, tile), ROUND_UP(seqLen, tile)] + __global FLOAT *output, // [Batch, seqLen/4, mNumHead * mHeadDim, 4] + __private const int tile, + __private const int seq_len, + __private const int seq_len_piece, + __private const int head_num, + __private const int head_dim, + __private const int seq_index +) { + + const int sl = get_global_id(0); // seqLen_Piece_4 + const int hd = get_global_id(1); // mHeadDim_4 + const int z = get_global_id(2); // Batch * mNumHead + DEAL_NON_UNIFORM_DIM3(sl, hd, z); + + const int b = z / head_num; + const int hn = z % head_num; + + const int seq_len_4 = (seq_len + 3) / 4; + + if(seq_index * seq_len_piece / 4 + sl >= seq_len_4) { + return; + } + const int seq_len_pack = seq_len_piece;//((seq_len + tile - 1) / tile) * tile; + const int head_dim_pack = ((head_dim + tile - 1) / tile) * tile; + + const int offset_inp = ((b * head_num + hn) * head_dim_pack + 4 * hd) * seq_len_pack + 4 * sl; + + const int offset_out = (((b * seq_len_4 + seq_index * seq_len_piece / 4 + sl) * head_num + hn) * head_dim + 4 * hd) * 4; + + // Q + FLOAT4 temp_0 = vload4(0, input + offset_inp); + FLOAT4 temp_1 = vload4(0, input + offset_inp + seq_len_pack); + FLOAT4 temp_2 = vload4(0, input + offset_inp + 2 * seq_len_pack); + FLOAT4 temp_3 = vload4(0, input + offset_inp + 3 * seq_len_pack); + + vstore4(temp_0, 0, output + offset_out); + if(4 * hd + 1 > head_dim) return; + vstore4(temp_1, 0, output + offset_out + 4); + if(4 * hd + 2 > head_dim) return; + vstore4(temp_2, 0, output + offset_out + 8); + if(4 * hd + 3 > head_dim) return; + vstore4(temp_3, 0, output + offset_out + 12); + +} diff --git a/source/backend/opencl/execution/cl/splitgelu_buf.cl b/source/backend/opencl/execution/cl/splitgelu_buf.cl new file mode 100644 index 000000000..e65e35736 --- /dev/null +++ b/source/backend/opencl/execution/cl/splitgelu_buf.cl @@ -0,0 +1,60 @@ +#ifdef MNN_SUPPORT_FP16 +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +#endif + +__kernel void splitgelu_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, + __global const FLOAT * input, + #ifdef DOUBLE_INPUTS + __global const FLOAT * input1, + #endif + __global FLOAT * output, + __private const int4 shape +){ + int3 pos = (int3)(get_global_id(0), get_global_id(1), get_global_id(2)); + if (pos.x < global_dim0 && pos.y < global_dim1 && pos.z < global_dim2) { + const int b = pos.x; + const int c_4 = pos.y; + +// The product of W and H is a multiple of 4 +#ifdef WH_4 + const int hw_4 = pos.z; + + const int channel_4 = (shape.y + 3) >> 2; + const int area_4 = (shape.z + 3) >> 2; + const int in_offset = ((b * channel_4 + c_4) * area_4 * 2 + hw_4) * 16; + const int out_offset = ((b * channel_4 + c_4) * area_4 + hw_4) * 16; + + float16 valueL = convert_float16(vload16(0, input + in_offset)); + float16 valueR = convert_float16(vload16(area_4, input + in_offset)); + + #ifdef DOUBLE_INPUTS + float4 valueConstL = convert_float4(vload4(hw, input1)); + float4 valueConstR = convert_float4(vload4(area_4+hw, input1)); + valueL += (float16)((float4)valueConstL.x, (float4)valueConstL.y, (float4)valueConstL.z, (float4)valueConstL.w); + valueR += (float16)((float4)valueConstR.x, (float4)valueConstR.y, (float4)valueConstR.z, (float4)valueConstR.w); + #endif + float16 out = (erf(valueR * (float16)0.7071067932881648) + (float16)1.0) * valueR * (float16)0.5; + out *= valueL; + vstore16(CONVERT_FLOAT16(out), 0, output + out_offset); +#else + const int hw = pos.z; + + const int channel_4 = (shape.y + 3) >> 2; + const int in_offset = ((b * channel_4 + c_4) * shape.z * 2 + hw) * 4; + const int out_offset = ((b * channel_4 + c_4) * shape.z + hw) * 4; + + float4 valueL = convert_float4(vload4(0, input + in_offset)); + float4 valueR = convert_float4(vload4(shape.z, input + in_offset)); + + #ifdef DOUBLE_INPUTS + float valueConstL = input1[hw]; + float valueConstR = input1[shape.z+hw]; + valueL += (float4)valueConstL; + valueR += (float4)valueConstR; + #endif + float4 out = (erf(valueR * (float4)0.7071067932881648) + (float4)1.0) * valueR * (float4)0.5; + out *= valueL; + vstore4(CONVERT_FLOAT4(out), 0, output + out_offset); +#endif + } +} diff --git a/source/backend/opencl/execution/cl/winogradTransform_buf.cl b/source/backend/opencl/execution/cl/winogradTransform_buf.cl index 6803850e7..efb799643 100644 --- a/source/backend/opencl/execution/cl/winogradTransform_buf.cl +++ b/source/backend/opencl/execution/cl/winogradTransform_buf.cl @@ -10,6 +10,85 @@ return; \ } +// [dstChannel, srcChannel, 3, 3] -> [4x4, srcChannelPad, dstChannelpad] (N, Kpad, Npad) +__kernel void winoTransWeightBuf2_3_1(GLOBAL_SIZE_DIM2 + __global const float* input, // 0 + __global FLOAT* output, + __private const int srcChannel, // 3 + __private const int dstChannel, + __private const int srcChannelPad, // 6 + __private const int dstChannelPad +) { + int2 pos = (int2)(get_global_id(0), get_global_id(1)); + UNIFORM_BOUNDRY_CHECK(pos.x, pos.y); + + const int src_c = pos.x; + const int dst_c = pos.y; + + const int out_offset = (0 * srcChannelPad + src_c) * dstChannelPad + dst_c; + const int out_offset_add = srcChannelPad * dstChannelPad; + if(src_c >= srcChannel || dst_c >= dstChannel) { + for(int i = 0; i < 16; i++) { + output[out_offset + i * out_offset_add] = (FLOAT)0; + } + return; + } + + const int in_offset = (dst_c * srcChannel + src_c) * 9; + FLOAT8 in = CONVERT_FLOAT8(vload8(0, input + in_offset)); + FLOAT in8 = input[in_offset+8]; + + FLOAT GB_00 = in.s0; + FLOAT GB_01 = in.s1; + FLOAT GB_02 = in.s2; + FLOAT GB_10 = in.s0 + in.s3 + in.s6; + FLOAT GB_11 = in.s1 + in.s4 + in.s7; + FLOAT GB_12 = in.s2 + in.s5 + in8; + FLOAT GB_20 = in.s0 - in.s3 + in.s6; + FLOAT GB_21 = in.s1 - in.s4 + in.s7; + FLOAT GB_22 = in.s2 - in.s5 + in8; + FLOAT GB_30 = in.s6; + FLOAT GB_31 = in.s7; + FLOAT GB_32 = in8; + + FLOAT GBGT_00 = GB_00; + FLOAT GBGT_01 = GB_00 + GB_01 + GB_02; + FLOAT GBGT_02 = GB_00 - GB_01 + GB_02; + FLOAT GBGT_03 = GB_02; + + FLOAT GBGT_10 = GB_10; + FLOAT GBGT_11 = GB_10 + GB_11 + GB_12; + FLOAT GBGT_12 = GB_10 - GB_11 + GB_12; + FLOAT GBGT_13 = GB_12; + + FLOAT GBGT_20 = GB_20; + FLOAT GBGT_21 = GB_20 + GB_21 + GB_22; + FLOAT GBGT_22 = GB_20 - GB_21 + GB_22; + FLOAT GBGT_23 = GB_22; + + FLOAT GBGT_30 = GB_30; + FLOAT GBGT_31 = GB_30 + GB_31 + GB_32; + FLOAT GBGT_32 = GB_30 - GB_31 + GB_32; + FLOAT GBGT_33 = GB_32; + + output[out_offset + 0 * out_offset_add] = GBGT_00; + output[out_offset + 1 * out_offset_add] = GBGT_01; + output[out_offset + 2 * out_offset_add] = GBGT_02; + output[out_offset + 3 * out_offset_add] = GBGT_03; + output[out_offset + 4 * out_offset_add] = GBGT_10; + output[out_offset + 5 * out_offset_add] = GBGT_11; + output[out_offset + 6 * out_offset_add] = GBGT_12; + output[out_offset + 7 * out_offset_add] = GBGT_13; + output[out_offset + 8 * out_offset_add] = GBGT_20; + output[out_offset + 9 * out_offset_add] = GBGT_21; + output[out_offset + 10 * out_offset_add] = GBGT_22; + output[out_offset + 11 * out_offset_add] = GBGT_23; + output[out_offset + 12 * out_offset_add] = GBGT_30; + output[out_offset + 13 * out_offset_add] = GBGT_31; + output[out_offset + 14 * out_offset_add] = GBGT_32; + output[out_offset + 15 * out_offset_add] = GBGT_33; +} + __kernel void winoTransSrcBuf2_3_1(GLOBAL_SIZE_DIM2 __global const FLOAT* uInput, // 0 __global FLOAT* uOutput, __private const int unitWidth, @@ -17,10 +96,14 @@ __kernel void winoTransSrcBuf2_3_1(GLOBAL_SIZE_DIM2 __private const int padX, __private const int padY, __private const int srcWidth, // 6 __private const int srcHeight, __private const int srcChannelC4, + __private const int dstHeightPad, __private const int srcChannelPad, __private const int batchOffset) { int2 pos = (int2)(get_global_id(0), get_global_id(1)); UNIFORM_BOUNDRY_CHECK(pos.x, pos.y); + if(pos.x >= unitWidth * unitHeight || pos.y >= srcChannelC4) { + return; + } int unitWidth_idx = pos.x % unitWidth; int unitHeight_idx = pos.x / unitWidth; int2 realPos = (int2)(unitWidth_idx, unitHeight_idx); @@ -183,26 +266,123 @@ __kernel void winoTransSrcBuf2_3_1(GLOBAL_SIZE_DIM2 FLOAT4 m23 = -S21 + S23; FLOAT4 m33 = -S31 + S33; - //NC4HW4 [alpha*alpha, srcChannelC4, dstHeight, 4] + //NC4HW4 [alpha*alpha, srcChannelPad, dstHeightPad] //index: [0, dstXOrigin, dstY, dstYOrigin % 4] - int out_offset = (((0*srcChannelC4 + dstXOrigin) * dstHeight + dstY) * 4 + dstYOrigin % 4)*4; - int batch_offset = srcChannelC4*dstHeight*16; - vstore4(+m00 - m20, 0, uOutput+out_offset+0*batch_offset); - vstore4(+(FLOAT)0.5f * m10 + (FLOAT)0.5f * m20, 0, uOutput+out_offset+1*batch_offset); - vstore4(-(FLOAT)0.5f * m10 + (FLOAT)0.5f * m20, 0, uOutput+out_offset+2*batch_offset); - vstore4(-m10 + m30, 0, uOutput+out_offset+3*batch_offset); - vstore4(+m01 - m21, 0, uOutput+out_offset+4*batch_offset); - vstore4(+(FLOAT)0.5f * m11 + (FLOAT)0.5f * m21, 0, uOutput+out_offset+5*batch_offset); - vstore4(-(FLOAT)0.5f * m11 + (FLOAT)0.5f * m21, 0, uOutput+out_offset+6*batch_offset); - vstore4(-m11 + m31, 0, uOutput+out_offset+7*batch_offset); - vstore4(+m02 - m22, 0, uOutput+out_offset+8*batch_offset); - vstore4(+(FLOAT)0.5f * m12 + (FLOAT)0.5f * m22, 0, uOutput+out_offset+9*batch_offset); - vstore4(-(FLOAT)0.5f * m12 + (FLOAT)0.5f * m22, 0, uOutput+out_offset+10*batch_offset); - vstore4(-m12 + m32, 0, uOutput+out_offset+11*batch_offset); - vstore4(+m03 - m23, 0, uOutput+out_offset+12*batch_offset); - vstore4(+(FLOAT)0.5f * m13 + (FLOAT)0.5f * m23, 0, uOutput+out_offset+13*batch_offset); - vstore4(-(FLOAT)0.5f * m13 + (FLOAT)0.5f * m23, 0, uOutput+out_offset+14*batch_offset); - vstore4(-m13 + m33, 0, uOutput+out_offset+15*batch_offset); + + int out_offset = (0*srcChannelPad + 4*dstXOrigin) * dstHeightPad + dstYOrigin; + int batch_offset = srcChannelPad*dstHeightPad; + + FLOAT4 res = (+m00 - m20); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (+(FLOAT)0.5f * m10 + (FLOAT)0.5f * m20); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-(FLOAT)0.5f * m10 + (FLOAT)0.5f * m20); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-m10 + m30); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + + out_offset += batch_offset; + res = (+m01 - m21); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (+(FLOAT)0.5f * m11 + (FLOAT)0.5f * m21); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-(FLOAT)0.5f * m11 + (FLOAT)0.5f * m21); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-m11 + m31); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (+m02 - m22); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (+(FLOAT)0.5f * m12 + (FLOAT)0.5f * m22); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-(FLOAT)0.5f * m12 + (FLOAT)0.5f * m22); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-m12 + m32); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (+m03 - m23); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (+(FLOAT)0.5f * m13 + (FLOAT)0.5f * m23); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-(FLOAT)0.5f * m13 + (FLOAT)0.5f * m23); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; + + out_offset += batch_offset; + res = (-m13 + m33); + uOutput[out_offset] = res.x; + uOutput[out_offset + dstHeightPad] = res.y; + uOutput[out_offset + dstHeightPad + dstHeightPad] = res.z; + uOutput[out_offset + dstHeightPad + dstHeightPad + dstHeightPad] = res.w; } } @@ -216,6 +396,8 @@ __kernel void winoTransDstBuf2_3_1(GLOBAL_SIZE_DIM2 __private const int dstWidth, __private const int dstHeight, __private const int dstChannelC4, + __private const int srcWidthPad, + __private const int dstChannelPad, __private const int batchOffset) { int2 pos = (int2)(get_global_id(0), get_global_id(1)); UNIFORM_BOUNDRY_CHECK(pos.x, pos.y); @@ -237,26 +419,28 @@ __kernel void winoTransDstBuf2_3_1(GLOBAL_SIZE_DIM2 int oyStart = realPos.y * 2; int oxStart = realPos.x * 2; - //NC4HW4 [dstChannelC4, alpha2, 4, UP_DIV(wUnit*hUnit,4)] x 4 - //index: [pos.y, 0, dstXOrigin % 4, dstX] - const int inp_offset = (((pos.y * 16 + 0) * 4 + dstXOrigin % 4) * srcWidth + dstX) * 4; - const int ic_offset = 16*srcWidth; - FLOAT4 S00 = vload4(0, uInput+inp_offset+ic_offset*0); - FLOAT4 S10 = vload4(0, uInput+inp_offset+ic_offset*1); - FLOAT4 S20 = vload4(0, uInput+inp_offset+ic_offset*2); - FLOAT4 S30 = vload4(0, uInput+inp_offset+ic_offset*3); - FLOAT4 S01 = vload4(0, uInput+inp_offset+ic_offset*4); - FLOAT4 S11 = vload4(0, uInput+inp_offset+ic_offset*5); - FLOAT4 S21 = vload4(0, uInput+inp_offset+ic_offset*6); - FLOAT4 S31 = vload4(0, uInput+inp_offset+ic_offset*7); - FLOAT4 S02 = vload4(0, uInput+inp_offset+ic_offset*8); - FLOAT4 S12 = vload4(0, uInput+inp_offset+ic_offset*9); - FLOAT4 S22 = vload4(0, uInput+inp_offset+ic_offset*10); - FLOAT4 S32 = vload4(0, uInput+inp_offset+ic_offset*11); - FLOAT4 S03 = vload4(0, uInput+inp_offset+ic_offset*12); - FLOAT4 S13 = vload4(0, uInput+inp_offset+ic_offset*13); - FLOAT4 S23 = vload4(0, uInput+inp_offset+ic_offset*14); - FLOAT4 S33 = vload4(0, uInput+inp_offset+ic_offset*15); + // [alpha2, srcWidthPad, dstChannelPad] + //index: [0, dstXOrigin, 4*oz] + + const int inp_offset = (0 * srcWidthPad + dstXOrigin) * dstChannelPad + 4*oz; + const int b_offset = dstChannelPad*srcWidthPad; + + FLOAT4 S00 = vload4(0, uInput+inp_offset+b_offset*0); + FLOAT4 S10 = vload4(0, uInput+inp_offset+b_offset*1); + FLOAT4 S20 = vload4(0, uInput+inp_offset+b_offset*2); + FLOAT4 S30 = vload4(0, uInput+inp_offset+b_offset*3); + FLOAT4 S01 = vload4(0, uInput+inp_offset+b_offset*4); + FLOAT4 S11 = vload4(0, uInput+inp_offset+b_offset*5); + FLOAT4 S21 = vload4(0, uInput+inp_offset+b_offset*6); + FLOAT4 S31 = vload4(0, uInput+inp_offset+b_offset*7); + FLOAT4 S02 = vload4(0, uInput+inp_offset+b_offset*8); + FLOAT4 S12 = vload4(0, uInput+inp_offset+b_offset*9); + FLOAT4 S22 = vload4(0, uInput+inp_offset+b_offset*10); + FLOAT4 S32 = vload4(0, uInput+inp_offset+b_offset*11); + FLOAT4 S03 = vload4(0, uInput+inp_offset+b_offset*12); + FLOAT4 S13 = vload4(0, uInput+inp_offset+b_offset*13); + FLOAT4 S23 = vload4(0, uInput+inp_offset+b_offset*14); + FLOAT4 S33 = vload4(0, uInput+inp_offset+b_offset*15); FLOAT4 m00 = +S00 + S01 + S02; FLOAT4 m10 = +S10 + S11 + S12; diff --git a/source/backend/opencl/execution/image/ConvExecution.cpp b/source/backend/opencl/execution/image/ConvExecution.cpp index 74673a469..f83de1223 100644 --- a/source/backend/opencl/execution/image/ConvExecution.cpp +++ b/source/backend/opencl/execution/image/ConvExecution.cpp @@ -187,9 +187,9 @@ ConvExecution::ConvExecution(const std::vector &inputs, const std::vec } mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(*(mResource->mKernelBuffer.get()), kernelBufferPtr); }else{ - std::vector filterImageShape{(int)inputChannel, (int)(UP_DIV(outputChannel, 4) * kernelWidth * kernelHeight)}; + std::vector filterImageShape{(int)ROUND_UP(inputChannel, 4), (int)(UP_DIV(outputChannel, 4) * kernelWidth * kernelHeight)}; std::shared_ptr filterBuffer( - Tensor::createDevice({outputChannel, inputChannel, kernelWidth, kernelHeight})); + Tensor::createDevice({outputChannel, ROUND_UP(inputChannel, 4), kernelWidth, kernelHeight})); size_t buffer_size = filterBuffer->elementSize() * sizeof(float); cl::Buffer filterBufferCL(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, buffer_size); @@ -199,7 +199,12 @@ ConvExecution::ConvExecution(const std::vector &inputs, const std::vec auto ptrCL = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(filterBufferCL, true, CL_MAP_WRITE, 0, buffer_size, nullptr, nullptr, &error); if(ptrCL != nullptr && error == CL_SUCCESS) { ::memset(ptrCL, 0, buffer_size); - ::memcpy(ptrCL, filterDataPtr, filterBuffer->size()); + int cpySrcNum = inputChannel * kernelWidth * kernelHeight; + int cpyDstNum = ROUND_UP(inputChannel, 4) * kernelWidth * kernelHeight; + int cpysize = cpySrcNum * sizeof(float); + for(int o = 0; o < outputChannel; ++o){ + ::memcpy((float*)ptrCL + o * cpyDstNum, filterDataPtr + o * cpySrcNum, cpysize); + } }else{ MNN_ERROR("Map error ptrCL == nullptr \n"); @@ -322,7 +327,7 @@ ErrorCode ConvExecution::onEncode(const std::vector &inputs, const std std::vector localWorkSize[total_kernel]; std::pair min_cost(INT_MAX, 0);//(min_time, min_index) - for(int knl_idx = 0; knl_idx < total_kernel; knl_idx++) { + for(int knl_idx = 0; knl_idx < 1; knl_idx++) { kernel[knl_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("conv_2d", kernelName[knl_idx], mResource->mBuildOptions); uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(kernel[knl_idx])); @@ -488,15 +493,18 @@ class ConvolutionCreator : public OpenCLBackend::Creator { #if defined(MNN_LOW_MEMORY) && not defined(MNN_OPENCL_BUFFER_CLOSED) { auto conv2dParams = op->main_as_Convolution2D(); - if ((static_cast(backend)->getMemory() == BackendConfig::Memory_Low) && (conv2dParams->quanParameter() != nullptr)) { + if (conv2dParams->quanParameter() != nullptr) { if (((conv2dParams->quanParameter()->type() == 4) || (conv2dParams->quanParameter()->type() == 1) || (conv2dParams->quanParameter()->type() == 2))) { - // Todo: support int4 inputchannel % 4 not equal 4 + if ((1 == conv2dParams->quanParameter()->type() || 2 == conv2dParams->quanParameter()->type()) && conv2dParams->quanParameter()->has_scaleInt()) { + // Don't support IDST-int8 because of error + return nullptr; + } return new ConvLowMemoryExecution(inputs, outputs, op, backend); } else { - MNN_ERROR("OpenCL Conv buf low memory init error. For Opencl Backend, only support low memory mode of int8 or int4 dequantization currently.\n"); - MNN_ASSERT(false); + //MNN_ERROR("OpenCL Conv buf low memory init error. For Opencl Backend, only support low memory mode of int8 or int4 dequantization currently.\n"); + return nullptr; } } } diff --git a/source/backend/opencl/execution/image/ConvExecution.hpp b/source/backend/opencl/execution/image/ConvExecution.hpp index 537a8aec2..2e68a5e41 100644 --- a/source/backend/opencl/execution/image/ConvExecution.hpp +++ b/source/backend/opencl/execution/image/ConvExecution.hpp @@ -27,8 +27,7 @@ struct ConvResource { std::shared_ptr mFilter; std::shared_ptr mBias; std::shared_ptr mKernelBuffer; - std::shared_ptr dequantScaleBuffer; - std::shared_ptr dequantOffsetBuffer; + std::shared_ptr dequantScaleOffset; std::vector mStrides{1, 1}; std::vector mDilations{1, 1}; std::set mBuildOptions; @@ -36,6 +35,7 @@ struct ConvResource { bool mConv1x1Opt = false; bool mWeightUseBuffer = false; bool gemmOpt = false; + int mBlockSize; int mKernelWidth; int mKernelHeight; int mOutputChannel; diff --git a/source/backend/opencl/execution/image/ConvLowMemoryExecution.cpp b/source/backend/opencl/execution/image/ConvLowMemoryExecution.cpp index cf9fc07fa..830e6737d 100644 --- a/source/backend/opencl/execution/image/ConvLowMemoryExecution.cpp +++ b/source/backend/opencl/execution/image/ConvLowMemoryExecution.cpp @@ -13,56 +13,53 @@ namespace OpenCL { // set mDequantScale mDequantOffset mNumQuantBit mFilterDataPtr from mConv2dParams void ConvLowMemoryExecution::getInfoFromOpLowMemory(std::shared_ptr & quanCommon) { quanCommon = ConvolutionCommon::load(mResource->mConv2dParams, this->backend(), false, true); - if ((mOpenCLBackend->getMemory() == BackendConfig::Memory_Low) && (mResource->mConv2dParams->quanParameter() != nullptr)) { + if (mResource->mConv2dParams->quanParameter() != nullptr) { mLowMemoryFlag = true; } else { MNN_ERROR("Conv buf low memory init error.\n"); MNN_ASSERT(false); } + + mResource->mInputChannel = quanCommon->weight.size() / (mResource->mKernelWidth * mResource->mKernelHeight * mResource->mOutputChannel); // set mNumQuantBit - if (quanCommon->quan->type() == 4) { - mNumQuantBit = 8; - } else if (quanCommon->quan->type() == 1 || quanCommon->quan->type() == 2) { + if(quanCommon->canUseInt4){ mNumQuantBit = 4; - } else {/* More types to be supported. */} + }else{ + mNumQuantBit = 8; + } // src of alpha in CPU float * dequantAlpha = quanCommon->alpha.get(); + int totalCount = quanCommon->alpha.size(); + if (quanCommon->asymmetric) { + totalCount /= 2; + } int numAlpha = mResource->mOutputChannel; + mResource->mBlockSize = totalCount / numAlpha; // set mDequantScale mDequantOffset int numAlphaPack = ROUND_UP(numAlpha, 16); - int bytes = mOpenCLBackend->fpBytes(); - mResource->dequantScaleBuffer.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, numAlphaPack * bytes)); - mResource->dequantOffsetBuffer.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, numAlphaPack * bytes)); + int mapSize = mResource->mBlockSize * numAlphaPack * sizeof(int32_t) * 2; + mResource->dequantScaleOffset.reset(new cl::Buffer(mOpenCLBackend->getOpenCLRuntime()->context(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, mapSize)); // transfer data from src in cpu to dst in gpu - cl_int resBias, resScale, resOffset; - void * dequantScaleBufferMap = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(*(mResource->dequantScaleBuffer.get()), true, CL_MAP_WRITE, 0, numAlphaPack * bytes, nullptr, nullptr, &resScale); - void * dequantOffsetBufferMap = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(*(mResource->dequantOffsetBuffer.get()), true, CL_MAP_WRITE, 0, numAlphaPack * bytes, nullptr, nullptr, &resOffset); - - ::memset(dequantScaleBufferMap, -1, numAlphaPack * bytes); - ::memset(dequantOffsetBufferMap, 0, numAlphaPack * bytes); - if (dequantScaleBufferMap != nullptr && dequantOffsetBufferMap != nullptr && resScale == CL_SUCCESS && resOffset == CL_SUCCESS) { - if (bytes == 2) { - if (quanCommon->asymmetric) { - for (int i = 0; i < numAlpha; ++i) { - ((half_float::half *)dequantOffsetBufferMap)[i] = (half_float::half)dequantAlpha[2 * i]; - ((half_float::half *)dequantScaleBufferMap)[i] = (half_float::half)dequantAlpha[2 * i + 1]; - } - } else { - for (int i = 0; i < numAlpha; ++i) { - ((half_float::half *)dequantScaleBufferMap)[i] = (half_float::half)dequantAlpha[i]; - ((half_float::half *)dequantOffsetBufferMap)[i] = 0.0f; + cl_int resScaleOffset; + void * dequantScaleOffsetBufferMap = mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueMapBuffer(*mResource->dequantScaleOffset.get(), true, CL_MAP_WRITE, 0, mapSize, nullptr, nullptr, &resScaleOffset); + // mBlockSize % 4 need equal 0 + if (dequantScaleOffsetBufferMap != nullptr && resScaleOffset == CL_SUCCESS) { + if (quanCommon->asymmetric) { + for (int i = 0; i < numAlpha; ++i) { + auto srcZ = dequantAlpha + i * mResource->mBlockSize * 2; + for(int j = 0; j < mResource->mBlockSize; ++j){ + float o = srcZ[2*j+0]; + float s = srcZ[2*j+1]; + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2] = s; + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2 + 1] = o; } } } else { - if (quanCommon->asymmetric) { - for (int i = 0; i < numAlpha; ++i) { - ((float *)dequantOffsetBufferMap)[i] = dequantAlpha[2 * i]; - ((float *)dequantScaleBufferMap)[i] = dequantAlpha[2 * i + 1]; - } - } else { - for (int i = 0; i < numAlpha; ++i) { - ((float *)dequantScaleBufferMap)[i] = dequantAlpha[i]; - ((float *)dequantOffsetBufferMap)[i] = 0.0f; + for (int i = 0; i < numAlpha; ++i) { + auto srcZ = dequantAlpha + i * mResource->mBlockSize; + for(int j = 0; j < mResource->mBlockSize; ++j){ + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2] = srcZ[j]; + ((float *)dequantScaleOffsetBufferMap)[(j * numAlphaPack + i) * 2 + 1] = 0.0f; } } } @@ -70,8 +67,7 @@ void ConvLowMemoryExecution::getInfoFromOpLowMemory(std::shared_ptrgetOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(*(mResource->dequantScaleBuffer.get()), dequantScaleBufferMap); - mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(*(mResource->dequantOffsetBuffer.get()), dequantOffsetBufferMap); + mOpenCLBackend->getOpenCLRuntime()->commandQueue().enqueueUnmapMemObject(*mResource->dequantScaleOffset.get(), dequantScaleOffsetBufferMap); // set mFilterDataPtr mFilterDataPtr = (void *)quanCommon->weight.get(); } @@ -96,10 +92,6 @@ void ConvLowMemoryExecution::set1x1WeightLowMemory(int packCout, int packCin, vo for(int o = 0; o < mResource->mOutputChannel; o++){ - float zero = 0; - if(quanCommon->asymmetric){ - zero = (-dequantAlpha[2 * o + 1])/dequantAlpha[2 * o]; - } int i = 0; for(; i < mResource->mInputChannel; i++){ int bufferIdx = (o/packCout) * packCin*packCout + (i/packCin)*packCin*ROUND_UP(mResource->mOutputChannel, packCout) + (i%packCin)*packCout + (o%packCout);//(Ci/packCin, Co/packCout, packCin, packCout) @@ -116,20 +108,6 @@ void ConvLowMemoryExecution::set1x1WeightLowMemory(int packCout, int packCin, vo } } else {/* More types to be supported. */} } - for(; i < ROUND_UP(mResource->mInputChannel, 4); i++){ - int bufferIdx = (o/packCout) * packCin*packCout + (i/packCin)*packCin*ROUND_UP(mResource->mOutputChannel, packCout) + (i%packCin)*packCout + (o%packCout);//(Ci/packCin, Co/packCout, packCin, packCout) - if (mNumQuantBit == 8) { - // int8 case - ((int8_t *)kernelBufferPtr)[bufferIdx] = (int8_t)(zero); - } else if (mNumQuantBit == 4){ - // int4 case - if (bufferIdx % 2 == 0) { - ((uint8_t *)kernelBufferPtr)[bufferIdx / 2] += (uint8_t)((zero + 8) * 16); - } else { - ((uint8_t *)kernelBufferPtr)[bufferIdx / 2] += (uint8_t)(zero + 8); - } - } - } } } else { MNN_ERROR("set1x1WeightLowMemory: Map error ptrCL == nullptr \n"); @@ -155,17 +133,10 @@ void ConvLowMemoryExecution::setGeneralWeightLowMemory(void* filterDataPtr, std: ::memset(ptrCL, 0, buffer_size); const int copy_size = mResource->mKernelWidth * mResource->mKernelHeight * sizeof(int8_t); for(int oc=0; ocmOutputChannel; oc++) { - float zero = 0; - if(quanCommon->asymmetric){ - zero = (-dequantAlpha[2 * oc + 1])/dequantAlpha[2 * oc]; - } int ic = 0; for(; icmInputChannel; ic++) { ::memcpy((int8_t *)ptrCL + (oc * ROUND_UP(mResource->mInputChannel, 4) + ic) * mResource->mKernelWidth * mResource->mKernelHeight, ((int8_t *)filterDataPtr) + (oc * mResource->mInputChannel + ic) * mResource->mKernelWidth * mResource->mKernelHeight, copy_size); } - for(; icmInputChannel, 4); ic++) { - ((int8_t *)ptrCL)[(oc * ROUND_UP(mResource->mInputChannel, 4) + ic) * mResource->mKernelWidth * mResource->mKernelHeight] = (int8_t)(zero); - } } } else { MNN_ERROR("setGeneralWeightLowMemory: Map error ptrCL == nullptr \n"); @@ -210,6 +181,7 @@ void ConvLowMemoryExecution::tune1x1CaseLowMemory(Tensor * input, Tensor * outpu const int inputWidth = inputShape.at(2); const int inputChannels = inputShape.at(3); const int inputChannelBlocks = UP_DIV(inputChannels, 4); + const int blockDim = mResource->mInputChannel / mResource->mBlockSize; std::string info = std::to_string(inputChannels) + "_" + std::to_string(outChannel) + "_" + std::to_string(mResource->mKernelHeight) + "_" + std::to_string(mResource->mKernelWidth) + "_" + std::to_string(mResource->mStrides[0]) + "_" + std::to_string(mResource->mStrides[1]) + "_" + std::to_string(mResource->mDilations[0]) + "_" + std::to_string(mResource->mDilations[1]); int inputImageShape[2] = {inputHeight, inputWidth}; int outputImageShape[2] = {height, width}; @@ -228,6 +200,9 @@ void ConvLowMemoryExecution::tune1x1CaseLowMemory(Tensor * input, Tensor * outpu cl_int ret = CL_SUCCESS; for(int knl_idx = 0; knl_idx < actual_kernel; knl_idx++) { std::set buildOption = mResource->mBuildOptions; + if(inputChannels % 4 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } kernel[knl_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("conv_2d", kernelName[knl_idx], buildOption); uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(kernel[knl_idx])); @@ -237,8 +212,7 @@ void ConvLowMemoryExecution::tune1x1CaseLowMemory(Tensor * input, Tensor * outpu ret |= kernel[knl_idx]->get().setArg(idx++, globalWorkSize[knl_idx][1]); ret |= kernel[knl_idx]->get().setArg(idx++, openCLImage(input)); ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->mKernelBuffer.get()); - ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->dequantScaleBuffer.get()); - ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->dequantOffsetBuffer.get()); + ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->dequantScaleOffset.get()); ret |= kernel[knl_idx]->get().setArg(idx++, openCLImage(mResource->mBias.get())); ret |= kernel[knl_idx]->get().setArg(idx++, openCLImage(output)); ret |= kernel[knl_idx]->get().setArg(idx++, sizeof(inputImageShape), inputImageShape); @@ -247,6 +221,8 @@ void ConvLowMemoryExecution::tune1x1CaseLowMemory(Tensor * input, Tensor * outpu ret |= kernel[knl_idx]->get().setArg(idx++, sizeof(stideShape), stideShape); ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(width, 4)); ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(outputShape.at(3), 4)); + ret |= kernel[knl_idx]->get().setArg(idx++, blockDim); + ret |= kernel[knl_idx]->get().setArg(idx++, inputChannels); std::pair, uint32_t> retTune; retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); @@ -262,14 +238,16 @@ void ConvLowMemoryExecution::tune1x1CaseLowMemory(Tensor * input, Tensor * outpu int min_index = min_cost.second; mGlobalWorkSize = {globalWorkSize[min_index][0], globalWorkSize[min_index][1]}; std::set buildOption = mResource->mBuildOptions; + if(inputChannels % 4 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("conv_2d", kernelName[min_index], buildOption); uint32_t idx = 0; ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[0]); ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[1]); ret |= unit.kernel->get().setArg(idx++, openCLImage(input)); ret |= unit.kernel->get().setArg(idx++, *mResource->mKernelBuffer.get()); - ret |= unit.kernel->get().setArg(idx++, *mResource->dequantScaleBuffer.get()); - ret |= unit.kernel->get().setArg(idx++, *mResource->dequantOffsetBuffer.get()); + ret |= unit.kernel->get().setArg(idx++, *mResource->dequantScaleOffset.get()); ret |= unit.kernel->get().setArg(idx++, openCLImage(mResource->mBias.get())); ret |= unit.kernel->get().setArg(idx++, openCLImage(output)); ret |= unit.kernel->get().setArg(idx++, sizeof(inputImageShape), inputImageShape); @@ -278,6 +256,8 @@ void ConvLowMemoryExecution::tune1x1CaseLowMemory(Tensor * input, Tensor * outpu ret |= unit.kernel->get().setArg(idx++, sizeof(stideShape), stideShape); ret |= unit.kernel->get().setArg(idx++, UP_DIV(width, 4)); ret |= unit.kernel->get().setArg(idx++, UP_DIV(outputShape.at(3), 4)); + ret |= unit.kernel->get().setArg(idx++, blockDim); + ret |= unit.kernel->get().setArg(idx++, inputChannels); MNN_CHECK_CL_SUCCESS(ret, "setArg Conv1x1LowMemory"); mOpenCLBackend->recordKernel2d(unit.kernel, mGlobalWorkSize, mLocalWorkSize); @@ -298,6 +278,7 @@ void ConvLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor * o const int inputWidth = inputShape.at(2); const int inputChannels = inputShape.at(3); const int inputChannelBlocks = UP_DIV(inputChannels, 4); + const int blockDim = mResource->mInputChannel / mResource->mBlockSize; std::string info = std::to_string(inputChannels) + "_" + std::to_string(outChannel) + "_" + std::to_string(mResource->mKernelHeight) + "_" + std::to_string(mResource->mKernelWidth) + "_" + std::to_string(mResource->mStrides[0]) + "_" + std::to_string(mResource->mStrides[1]) + "_" + std::to_string(mResource->mDilations[0]) + "_" + std::to_string(mResource->mDilations[1]); int inputImageShape[2] = {inputHeight, inputWidth}; int outputImageShape[2] = {height, width}; @@ -318,6 +299,9 @@ void ConvLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor * o // MNN_PRINT("Checking kernel %d.\n", knlCheck); for (int knl_idx = 0; knl_idx < actual_kernel; knl_idx++) { std::set buildOption = mResource->mBuildOptions; + if(inputChannels % 4 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } kernel[knl_idx] = mOpenCLBackend->getOpenCLRuntime()->buildKernel("conv_2d", kernelName[knl_idx], buildOption); uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(kernel[knl_idx])); @@ -328,8 +312,7 @@ void ConvLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor * o ret |= kernel[knl_idx]->get().setArg(idx++, globalWorkSize[knl_idx][1]); ret |= kernel[knl_idx]->get().setArg(idx++, openCLImage(input)); ret |= kernel[knl_idx]->get().setArg(idx++, openCLBuffer(mResource->mFilter.get())); - ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->dequantScaleBuffer.get()); - ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->dequantOffsetBuffer.get()); + ret |= kernel[knl_idx]->get().setArg(idx++, *mResource->dequantScaleOffset.get()); ret |= kernel[knl_idx]->get().setArg(idx++, openCLImage(mResource->mBias.get())); ret |= kernel[knl_idx]->get().setArg(idx++, openCLImage(output)); ret |= kernel[knl_idx]->get().setArg(idx++, sizeof(inputImageShape), inputImageShape); @@ -342,6 +325,8 @@ void ConvLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor * o ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(width, itemW[knl_idx])); ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(outputShape.at(3), 4)); ret |= kernel[knl_idx]->get().setArg(idx++, UP_DIV(height, itemH[knl_idx])); + ret |= kernel[knl_idx]->get().setArg(idx++, blockDim); + ret |= kernel[knl_idx]->get().setArg(idx++, inputChannels); MNN_CHECK_CL_SUCCESS(ret, "setArg ConvLowMemory Kernel Select"); std::pair, int> retTune; retTune = localWS2DDefault(globalWorkSize[knl_idx], maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName[knl_idx] + info, kernel[knl_idx]); @@ -355,6 +340,9 @@ void ConvLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor * o mGlobalWorkSize = {globalWorkSize[min_index][0], globalWorkSize[min_index][1]}; std::set buildOption = mResource->mBuildOptions; + if(inputChannels % 4 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("conv_2d", kernelName[min_index], buildOption); uint32_t idx = 0; @@ -363,8 +351,7 @@ void ConvLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor * o ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[1]); ret |= unit.kernel->get().setArg(idx++, openCLImage(input)); ret |= unit.kernel->get().setArg(idx++, openCLBuffer(mResource->mFilter.get())); - ret |= unit.kernel->get().setArg(idx++, *mResource->dequantScaleBuffer.get()); - ret |= unit.kernel->get().setArg(idx++, *mResource->dequantOffsetBuffer.get()); + ret |= unit.kernel->get().setArg(idx++, *mResource->dequantScaleOffset.get()); ret |= unit.kernel->get().setArg(idx++, openCLImage(mResource->mBias.get())); ret |= unit.kernel->get().setArg(idx++, openCLImage(output)); ret |= unit.kernel->get().setArg(idx++, sizeof(inputImageShape), inputImageShape); @@ -377,6 +364,8 @@ void ConvLowMemoryExecution::tuneGeneralCaseLowMemory(Tensor * input, Tensor * o ret |= unit.kernel->get().setArg(idx++, UP_DIV(width, itemW[min_index])); ret |= unit.kernel->get().setArg(idx++, UP_DIV(outputShape.at(3), 4)); ret |= unit.kernel->get().setArg(idx++, UP_DIV(height, itemH[min_index])); + ret |= unit.kernel->get().setArg(idx++, blockDim); + ret |= unit.kernel->get().setArg(idx++, inputChannels); MNN_CHECK_CL_SUCCESS(ret, "setArg ConvLowMemory"); mOpenCLBackend->recordKernel2d(unit.kernel, mGlobalWorkSize, mLocalWorkSize); @@ -394,6 +383,7 @@ void ConvLowMemoryExecution::tuneGemmLowMemory(Tensor * input, Tensor * output) const int batch = outputShape.at(0); const int inputChannelBlocks = UP_DIV(inputChannels, 4); const int outputChannelBlocks = UP_DIV(outChannel, 4); + const int blockDim = mResource->mInputChannel / mResource->mBlockSize; std::string kernelname = "gemm_conv"; int global_x = outputChannelBlocks; int global_y = batch; @@ -403,7 +393,11 @@ void ConvLowMemoryExecution::tuneGemmLowMemory(Tensor * input, Tensor * output) global_y = UP_DIV(batch, 2); } std::string info = std::to_string(inputChannels) + "_" + std::to_string(outChannel); - unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm", kernelname, mResource->mBuildOptions); + std::set buildOption = mResource->mBuildOptions; + if(inputChannels % 4 != 0){ + buildOption.emplace("-DINPUT_CHANNEL_LEAVE"); + } + unit.kernel = mOpenCLBackend->getOpenCLRuntime()->buildKernel("gemm", kernelname, buildOption); uint32_t maxWorkGroupSize = static_cast(mOpenCLBackend->getOpenCLRuntime()->getMaxWorkGroupSize(unit.kernel)); mGlobalWorkSize = {static_cast(global_x), static_cast(global_y)}; // MNN_PRINT("Kernel is %d.\n", min_index); @@ -413,13 +407,14 @@ void ConvLowMemoryExecution::tuneGemmLowMemory(Tensor * input, Tensor * output) ret |= unit.kernel->get().setArg(idx++, mGlobalWorkSize[1]); ret |= unit.kernel->get().setArg(idx++, openCLImage(input)); ret |= unit.kernel->get().setArg(idx++, *mResource->mKernelBuffer.get()); - ret |= unit.kernel->get().setArg(idx++, *mResource->dequantScaleBuffer.get()); - ret |= unit.kernel->get().setArg(idx++, *mResource->dequantOffsetBuffer.get()); + ret |= unit.kernel->get().setArg(idx++, *mResource->dequantScaleOffset.get()); ret |= unit.kernel->get().setArg(idx++, openCLImage(mResource->mBias.get())); ret |= unit.kernel->get().setArg(idx++, openCLImage(output)); ret |= unit.kernel->get().setArg(idx++, static_cast(outputChannelBlocks)); ret |= unit.kernel->get().setArg(idx++, static_cast(inputChannelBlocks)); ret |= unit.kernel->get().setArg(idx++, static_cast(batch)); + ret |= unit.kernel->get().setArg(idx++, static_cast(blockDim)); + ret |= unit.kernel->get().setArg(idx++, static_cast(inputChannels)); MNN_CHECK_CL_SUCCESS(ret, "setArg gemm_conv"); mLocalWorkSize = localWS2DDefault(mGlobalWorkSize, maxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelname + info, unit.kernel).first; @@ -449,16 +444,16 @@ ConvLowMemoryExecution::ConvLowMemoryExecution(const std::vector &inpu mResource->mKernelWidth = conv2dCommonParams->kernelX(); mResource->mKernelHeight = conv2dCommonParams->kernelY(); mResource->mOutputChannel = conv2dCommonParams->outputCount(); - mResource->mInputChannel = conv2dCommonParams->inputCount(); std::shared_ptr quanCommon; // set mDequantScale, mDequantOffset, mFilterDataPtr // prepare mDequantScale mDequantOffset mFilterDataPtr getInfoFromOpLowMemory(quanCommon); //select opt conv method - if (mResource->mKernelHeight == mResource->mKernelWidth && mResource->mKernelHeight == 1 && mResource->mStrides[0] == 1 && mResource->mStrides[1] == 1) { + if (mResource->mKernelHeight == mResource->mKernelWidth && mResource->mKernelHeight == 1 && mResource->mStrides[0] == 1 && mResource->mStrides[1] == 1 && mPaddings[0] == 0 && mPaddings[1] == 0) { // set mKernelBuffer for 1x1 case // At first, set packCout equal to 4 set1x1WeightLowMemory(4, 4, mFilterDataPtr, quanCommon); + mResource->mConv1x1Opt = true; }else { // set mFilter for not 1x1 case setGeneralWeightLowMemory(mFilterDataPtr, quanCommon); @@ -516,12 +511,11 @@ ErrorCode ConvLowMemoryExecution::onEncode(const std::vector &inputs, auto padding = ConvolutionCommon::convolutionPad(input, output, mResource->mConv2dCommonParams); mPaddings[0] = padding.second;//padY mPaddings[1] = padding.first;//padX - mResource->gemmOpt = (mResource->mKernelHeight == mResource->mKernelWidth && mResource->mKernelHeight == 1 && mPaddings[0] == 0 && mPaddings[1] == 0 && mResource->mStrides[0] == 1 && mResource->mStrides[1] == 1 && inputs[0]->width() == 1 && inputs[0]->height() == 1); - mResource->mConv1x1Opt = (mResource->mKernelHeight == mResource->mKernelWidth && mResource->mKernelHeight == 1 && mPaddings[0] == 0 && mPaddings[1] == 0 && mResource->mStrides[0] == 1 && mResource->mStrides[1] == 1 && inputs[0]->width() >= 4); - if (mResource->mConv1x1Opt) { - tune1x1CaseLowMemory(input, output); - } else if(mResource->gemmOpt){ + mResource->gemmOpt = (mResource->mConv1x1Opt && inputs[0]->width() == 1 && inputs[0]->height() == 1); + if (mResource->gemmOpt) { tuneGemmLowMemory(input, output); + } else if(mResource->mConv1x1Opt){ + tune1x1CaseLowMemory(input, output); } else { tuneGeneralCaseLowMemory(input, output); } diff --git a/source/backend/opencl/execution/image/RasterExecution.cpp b/source/backend/opencl/execution/image/RasterExecution.cpp index 7b2c0109f..15cdb6235 100644 --- a/source/backend/opencl/execution/image/RasterExecution.cpp +++ b/source/backend/opencl/execution/image/RasterExecution.cpp @@ -42,15 +42,11 @@ ErrorCode RasterExecution::onEncode(const std::vector &____inputs, con bool cancombine = CanCombine(outputs); // Alloc Temp buffer auto bufferPool = ((OpenCLBackend *)backend())->getBufferPool(); - auto bufferUnitSize = runtime->isSupportedFP16() ? sizeof(half_float::half) : sizeof(float); - if(output->getType().code == halide_type_int || output->getType().code == halide_type_uint) { - if(output->getType().bits == 8){ - bufferUnitSize = 1; - } else if(output->getType().bits == 32){ - bufferUnitSize = 1; - } + if(output->getType().code == halide_type_float && runtime->isSupportedFP16()) { + mTempOutput = bufferPool->alloc(output->usize()/2); + }else{ + mTempOutput = bufferPool->alloc(output->usize()); } - mTempOutput = bufferPool->alloc(output->elementSize() * bufferUnitSize); bufferPool->recycle(mTempOutput); auto originNum = mTempInput.size(); diff --git a/source/backend/opencl/schema/CLCache.fbs b/source/backend/opencl/schema/CLCache.fbs index 5be19886d..d53ce263f 100644 --- a/source/backend/opencl/schema/CLCache.fbs +++ b/source/backend/opencl/schema/CLCache.fbs @@ -24,10 +24,16 @@ table Autotuning { timeCost:uint; } +table GemmInfo { + gemmSize:[uint]; + paramInfo:[uint]; +} + table Cache { programs:[Shader]; tunings:[Autotuning]; tuned:[OpInfo]; + gemm:[GemmInfo]; } root_type Cache; diff --git a/source/backend/opencl/schema/current/CLCache_generated.h b/source/backend/opencl/schema/current/CLCache_generated.h index 8b3fdbddf..5918d6049 100644 --- a/source/backend/opencl/schema/current/CLCache_generated.h +++ b/source/backend/opencl/schema/current/CLCache_generated.h @@ -20,6 +20,9 @@ struct ShaderT; struct Autotuning; struct AutotuningT; +struct GemmInfo; +struct GemmInfoT; + struct Cache; struct CacheT; @@ -31,6 +34,8 @@ inline const flatbuffers::TypeTable *ShaderTypeTable(); inline const flatbuffers::TypeTable *AutotuningTypeTable(); +inline const flatbuffers::TypeTable *GemmInfoTypeTable(); + inline const flatbuffers::TypeTable *CacheTypeTable(); struct TensorInfoT : public flatbuffers::NativeTable { @@ -350,11 +355,77 @@ inline flatbuffers::Offset CreateAutotuning( flatbuffers::Offset CreateAutotuning(flatbuffers::FlatBufferBuilder &_fbb, const AutotuningT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct GemmInfoT : public flatbuffers::NativeTable { + typedef GemmInfo TableType; + std::vector gemmSize; + std::vector paramInfo; + GemmInfoT() { + } +}; + +struct GemmInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GemmInfoT NativeTableType; + static const flatbuffers::TypeTable *MiniReflectTypeTable() { + return GemmInfoTypeTable(); + } + const flatbuffers::Vector *gemmSize() const { + return GetPointer *>(4); + } + const flatbuffers::Vector *paramInfo() const { + return GetPointer *>(6); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, 4) && + verifier.VerifyVector(gemmSize()) && + VerifyOffset(verifier, 6) && + verifier.VerifyVector(paramInfo()) && + verifier.EndTable(); + } + GemmInfoT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GemmInfoT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GemmInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct GemmInfoBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_gemmSize(flatbuffers::Offset> gemmSize) { + fbb_.AddOffset(4, gemmSize); + } + void add_paramInfo(flatbuffers::Offset> paramInfo) { + fbb_.AddOffset(6, paramInfo); + } + explicit GemmInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GemmInfoBuilder &operator=(const GemmInfoBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateGemmInfo( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> gemmSize = 0, + flatbuffers::Offset> paramInfo = 0) { + GemmInfoBuilder builder_(_fbb); + builder_.add_paramInfo(paramInfo); + builder_.add_gemmSize(gemmSize); + return builder_.Finish(); +} + +flatbuffers::Offset CreateGemmInfo(flatbuffers::FlatBufferBuilder &_fbb, const GemmInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct CacheT : public flatbuffers::NativeTable { typedef Cache TableType; std::vector> programs; std::vector> tunings; std::vector> tuned; + std::vector> gemm; CacheT() { } }; @@ -373,6 +444,9 @@ struct Cache FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *tuned() const { return GetPointer> *>(8); } + const flatbuffers::Vector> *gemm() const { + return GetPointer> *>(10); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, 4) && @@ -384,6 +458,9 @@ struct Cache FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffset(verifier, 8) && verifier.VerifyVector(tuned()) && verifier.VerifyVectorOfTables(tuned()) && + VerifyOffset(verifier, 10) && + verifier.VerifyVector(gemm()) && + verifier.VerifyVectorOfTables(gemm()) && verifier.EndTable(); } CacheT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; @@ -403,6 +480,9 @@ struct CacheBuilder { void add_tuned(flatbuffers::Offset>> tuned) { fbb_.AddOffset(8, tuned); } + void add_gemm(flatbuffers::Offset>> gemm) { + fbb_.AddOffset(10, gemm); + } explicit CacheBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -419,8 +499,10 @@ inline flatbuffers::Offset CreateCache( flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset>> programs = 0, flatbuffers::Offset>> tunings = 0, - flatbuffers::Offset>> tuned = 0) { + flatbuffers::Offset>> tuned = 0, + flatbuffers::Offset>> gemm = 0) { CacheBuilder builder_(_fbb); + builder_.add_gemm(gemm); builder_.add_tuned(tuned); builder_.add_tunings(tunings); builder_.add_programs(programs); @@ -560,6 +642,35 @@ inline flatbuffers::Offset CreateAutotuning(flatbuffers::FlatBufferB _timeCost); } +inline GemmInfoT *GemmInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new GemmInfoT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void GemmInfo::UnPackTo(GemmInfoT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = gemmSize(); if (_e) { _o->gemmSize.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->gemmSize[_i] = _e->Get(_i); } } }; + { auto _e = paramInfo(); if (_e) { _o->paramInfo.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->paramInfo[_i] = _e->Get(_i); } } }; +} + +inline flatbuffers::Offset GemmInfo::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GemmInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGemmInfo(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateGemmInfo(flatbuffers::FlatBufferBuilder &_fbb, const GemmInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GemmInfoT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _gemmSize = _o->gemmSize.size() ? _fbb.CreateVector(_o->gemmSize) : 0; + auto _paramInfo = _o->paramInfo.size() ? _fbb.CreateVector(_o->paramInfo) : 0; + return CLCache::CreateGemmInfo( + _fbb, + _gemmSize, + _paramInfo); +} + inline CacheT *Cache::UnPack(const flatbuffers::resolver_function_t *_resolver) const { auto _o = new CacheT(); UnPackTo(_o, _resolver); @@ -572,6 +683,7 @@ inline void Cache::UnPackTo(CacheT *_o, const flatbuffers::resolver_function_t * { auto _e = programs(); if (_e) { _o->programs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->programs[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }; { auto _e = tunings(); if (_e) { _o->tunings.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->tunings[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }; { auto _e = tuned(); if (_e) { _o->tuned.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->tuned[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }; + { auto _e = gemm(); if (_e) { _o->gemm.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->gemm[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }; } inline flatbuffers::Offset Cache::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CacheT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -585,11 +697,13 @@ inline flatbuffers::Offset CreateCache(flatbuffers::FlatBufferBuilder &_f auto _programs = _o->programs.size() ? _fbb.CreateVector> (_o->programs.size(), [](size_t i, _VectorArgs *__va) { return CreateShader(*__va->__fbb, __va->__o->programs[i].get(), __va->__rehasher); }, &_va ) : 0; auto _tunings = _o->tunings.size() ? _fbb.CreateVector> (_o->tunings.size(), [](size_t i, _VectorArgs *__va) { return CreateAutotuning(*__va->__fbb, __va->__o->tunings[i].get(), __va->__rehasher); }, &_va ) : 0; auto _tuned = _o->tuned.size() ? _fbb.CreateVector> (_o->tuned.size(), [](size_t i, _VectorArgs *__va) { return CreateOpInfo(*__va->__fbb, __va->__o->tuned[i].get(), __va->__rehasher); }, &_va ) : 0; + auto _gemm = _o->gemm.size() ? _fbb.CreateVector> (_o->gemm.size(), [](size_t i, _VectorArgs *__va) { return CreateGemmInfo(*__va->__fbb, __va->__o->gemm[i].get(), __va->__rehasher); }, &_va ) : 0; return CLCache::CreateCache( _fbb, _programs, _tunings, - _tuned); + _tuned, + _gemm); } inline const flatbuffers::TypeTable *TensorInfoTypeTable() { @@ -665,24 +779,42 @@ inline const flatbuffers::TypeTable *AutotuningTypeTable() { return &tt; } +inline const flatbuffers::TypeTable *GemmInfoTypeTable() { + static const flatbuffers::TypeCode type_codes[] = { + { flatbuffers::ET_UINT, 1, -1 }, + { flatbuffers::ET_UINT, 1, -1 } + }; + static const char * const names[] = { + "gemmSize", + "paramInfo" + }; + static const flatbuffers::TypeTable tt = { + flatbuffers::ST_TABLE, 2, type_codes, nullptr, nullptr, names + }; + return &tt; +} + inline const flatbuffers::TypeTable *CacheTypeTable() { static const flatbuffers::TypeCode type_codes[] = { { flatbuffers::ET_SEQUENCE, 1, 0 }, { flatbuffers::ET_SEQUENCE, 1, 1 }, - { flatbuffers::ET_SEQUENCE, 1, 2 } + { flatbuffers::ET_SEQUENCE, 1, 2 }, + { flatbuffers::ET_SEQUENCE, 1, 3 } }; static const flatbuffers::TypeFunction type_refs[] = { ShaderTypeTable, AutotuningTypeTable, - OpInfoTypeTable + OpInfoTypeTable, + GemmInfoTypeTable }; static const char * const names[] = { "programs", "tunings", - "tuned" + "tuned", + "gemm" }; static const flatbuffers::TypeTable tt = { - flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, names + flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, names }; return &tt; } diff --git a/source/core/Pipeline.cpp b/source/core/Pipeline.cpp index 7033108c3..2798239e5 100644 --- a/source/core/Pipeline.cpp +++ b/source/core/Pipeline.cpp @@ -41,7 +41,7 @@ static bool _supportQuant(const Op* op, const std::vector& inputs, cons case OpType_ConvInt8: case OpType_DepthwiseConvInt8: return true; - // case OpType_Eltwise: + // case OpType_Eltwise: case OpType_Raster: { for (auto input : inputs) { @@ -69,7 +69,7 @@ static bool _supportQuant(const Op* op, const std::vector& inputs, cons } else { return false; } - case OpType_BinaryOp: + case OpType_BinaryOp: return true; case OpType_Softmax: return true; @@ -80,7 +80,11 @@ static bool _supportQuant(const Op* op, const std::vector& inputs, cons case OpType_LayerNorm: return true; case OpType_UnaryOp: - return true; + if (op->main_as_UnaryOp()->tableInt8() || op->main_as_UnaryOp()->opType() == UnaryOpOperation_NEG || op->main_as_UnaryOp()->opType() == UnaryOpOperation_ABS || op->main_as_UnaryOp()->opType() == UnaryOpOperation_SIGN) { + return true; + } else { + return false; + } case OpType_PReLU: return true; default: diff --git a/source/core/Tensor.cpp b/source/core/Tensor.cpp index 4165f1ab7..28d5076a8 100644 --- a/source/core/Tensor.cpp +++ b/source/core/Tensor.cpp @@ -240,7 +240,7 @@ void Tensor::setType(int type) { mBuffer.type = halide_type_of(); break; default: - MNN_PRINT("Unsupported data type!"); + MNN_PRINT("Unsupported data type! %d\n", type); MNN_ASSERT(false); break; } diff --git a/test/MNNTestSuite.cpp b/test/MNNTestSuite.cpp index 157a54051..2b3aeb52a 100644 --- a/test/MNNTestSuite.cpp +++ b/test/MNNTestSuite.cpp @@ -56,6 +56,9 @@ int MNNTestSuite::run(const char* key, int precision, const char* flag) { } } } + for (auto& iter : runTimes) { + MNN_PRINT("%s cost time: %.3f ms\n", iter.first.c_str(), iter.second); + } if (wrongs.empty()) { MNN_PRINT("√√√ all <%s> tests passed.\n", key); } @@ -63,9 +66,6 @@ int MNNTestSuite::run(const char* key, int precision, const char* flag) { MNN_PRINT("Error: %s\n", wrong.c_str()); } printTestResult(wrongs.size(), runUnit - wrongs.size(), flag); - for (auto& iter : runTimes) { - MNN_PRINT("%s cost time: %.3f ms\n", iter.first.c_str(), iter.second); - } return wrongs.size(); } @@ -91,6 +91,9 @@ int MNNTestSuite::runAll(int precision, const char* flag) { wrongs.emplace_back(test->name); } } + for (auto& iter : runTimes) { + MNN_PRINT("%s cost time: %.3f ms\n", iter.first.c_str(), iter.second); + } if (wrongs.empty()) { MNN_PRINT("√√√ all tests passed.\n"); } @@ -98,8 +101,5 @@ int MNNTestSuite::runAll(int precision, const char* flag) { MNN_PRINT("Error: %s\n", wrong.c_str()); } printTestResult(wrongs.size(), suite->mTests.size() - wrongs.size(), flag); - for (auto& iter : runTimes) { - MNN_PRINT("%s cost time: %.3f ms\n", iter.first.c_str(), iter.second); - } return wrongs.size(); } diff --git a/test/core/BackendTest.cpp b/test/core/BackendTest.cpp index dd3381b9f..c40472ad2 100644 --- a/test/core/BackendTest.cpp +++ b/test/core/BackendTest.cpp @@ -572,7 +572,7 @@ bool nchwTonhwc(std::shared_ptr bn) { auto backendCopyData = hostTensorNHWC->host(); for (int i = 0; i < elementSize; ++i) { if (abs(backendCopyData[i] - temp[i]) >= F32_BF16_MAX_LOSS) { //Error of converting from float32 to bf16 is more than 0.001 - MNN_PRINT("Error for bn:%d, %f -> %f. F32_BF16_MAX_LOSS:%f\n", i, hostData[i], backendCopyData[i], F32_BF16_MAX_LOSS); + MNN_PRINT("Error for bn:%d, %f -> %f. F32_BF16_MAX_LOSS:%f\n", i, temp[i], backendCopyData[i], F32_BF16_MAX_LOSS); return false; } } diff --git a/tools/converter/source/onnx/IdentityOnnx.cpp b/tools/converter/source/onnx/IdentityOnnx.cpp index af2f7dbbd..d5dcb9dfe 100644 --- a/tools/converter/source/onnx/IdentityOnnx.cpp +++ b/tools/converter/source/onnx/IdentityOnnx.cpp @@ -24,3 +24,21 @@ void IdentityOnnx::run(MNN::OpT *dstOp, const onnx::NodeProto *onnxNode, } REGISTER_CONVERTER(IdentityOnnx, Identity); + + +DECLARE_OP_CONVERTER(DropoutOnnx); + +MNN::OpType DropoutOnnx::opType() { + return MNN::OpType_Dropout; +} +MNN::OpParameter DropoutOnnx::type() { + return MNN::OpParameter_NONE; +} + +void DropoutOnnx::run(MNN::OpT *dstOp, const onnx::NodeProto *onnxNode, + OnnxScope* scope) { + // Do nothing + return; +} + +REGISTER_CONVERTER(DropoutOnnx, Dropout); diff --git a/tools/converter/source/optimizer/merge/FuseFmhaV2.cpp b/tools/converter/source/optimizer/merge/FuseFmhaV2.cpp index 7c8ee3b85..fdd90a61b 100644 --- a/tools/converter/source/optimizer/merge/FuseFmhaV2.cpp +++ b/tools/converter/source/optimizer/merge/FuseFmhaV2.cpp @@ -247,6 +247,252 @@ FuseFmhaV2::FuseFmhaV2() { TemplateMerge::getInstance("Merge").insertTemplate("FuseFmhaV2", match, fold); } +class FuseSelfAttentionV2 { +public: + FuseSelfAttentionV2(); +private: + EXPRP node_q, node_k, node_v; + VARP var_q_weight, var_k_weight, var_v_weight; + VARP fmha_v2_input_; + int mNumHeads; +}; + +FuseSelfAttentionV2::FuseSelfAttentionV2() { + auto match = [this](EXPRP expr) -> bool { + auto config = Global::Get(); + if(!config->transformerFuse) { + return false; + } + // whether reshape + if (!expr->get() || !helpers::IsReshape(expr)) { + return false; + } + + EXPRP x, y, z; + + // whether transpose + x = expr->inputs().at(0)->expr().first; + if (!expr->get() || !helpers::IsTranspose(x)) { + return false; + } + z = x; + + // whether reshape + x = z->inputs().at(0)->expr().first; + if (!helpers::IsReshape(x)) { + return false; + } + z = x; + + // whether Einsum/MatMul + x = z->inputs().at(0)->expr().first; + if (helpers::IsMatMul(x)) { + z = x; + } else { + return false; + } + + // whether V + auto qk_pre = z->inputs().at(0)->expr().first; + auto v_pre = z->inputs().at(1)->expr().first; + z = GetFmhaV2BlockCommonNode(v_pre); + if (z == nullptr) { + return false; + } + mNumHeads = GetFmhaV2NumHeads(z); + if (mNumHeads == 0) { + return false; + } + node_v = z->inputs().at(0)->expr().first; + if (!helpers::IsMatMul(node_v)) { + return false; + } + + // whether cast + if (helpers::IsCast(qk_pre)) { + qk_pre = qk_pre->inputs().at(0)->expr().first; + } + z = qk_pre; + // whether softmax + if (!helpers::IsSoftmax(z)) { + return false; + } + + //whether add zero + x = z->inputs().at(0)->expr().first; + if (helpers::IsBinaryAdd(x)) { + z = x; + } else { + return false; + } + + //add two inputs + auto x_0 = z->inputs().at(0)->expr().first; + bool add_0_zero = false; + if (helpers::IsBinaryMul(x_0)) { + auto temp_0 = x_0->inputs().at(0)->expr().first; + auto temp_1 = x_0->inputs().at(1)->expr().first; + if (helpers::IsConstant(temp_0)) { + float mul_y = x_0->inputs().at(0)->readMap()[0]; + if(mul_y >= -0.0000001 && mul_y <= 0.0000001) { + add_0_zero = true; + } + } + if (helpers::IsConstant(temp_1)) { + float mul_y = x_0->inputs().at(1)->readMap()[0]; + if(mul_y >= -0.0000001 && mul_y <= 0.0000001) { + add_0_zero = true; + } + } + } else { + return false; + } + + auto x_1 = z->inputs().at(1)->expr().first; + bool add_1_zero = false; + if (helpers::IsBinaryMul(x_1)) { + auto temp_0 = x_1->inputs().at(0)->expr().first; + auto temp_1 = x_1->inputs().at(1)->expr().first; + if (helpers::IsConstant(temp_0)) { + float mul_y = x_1->inputs().at(0)->readMap()[0]; + if(mul_y >= -0.0000001 && mul_y <= 0.0000001) { + add_1_zero = true; + } + } + if (helpers::IsConstant(temp_1)) { + float mul_y = x_1->inputs().at(1)->readMap()[0]; + if(mul_y >= -0.0000001 && mul_y <= 0.0000001) { + add_1_zero = true; + } + } + } else { + return false; + } + + if(add_0_zero && !add_1_zero) { + x = z->inputs().at(1)->expr().first; + if(helpers::IsConstant(x->inputs().at(0)->expr().first)) { + x = x->inputs().at(1)->expr().first; + } else { + x = x->inputs().at(0)->expr().first; + } + } else if(!add_0_zero && add_1_zero) { + x = z->inputs().at(0)->expr().first; + if(helpers::IsConstant(x->inputs().at(0)->expr().first)) { + x = x->inputs().at(1)->expr().first; + } else { + x = x->inputs().at(0)->expr().first; + } + } else { + return false; + } + + //whether matmul + if (helpers::IsMatMul(x)) { + z = x; + } else { + return false; + } + + auto q_pre = z->inputs().at(0)->expr().first; + auto k_pre = z->inputs().at(1)->expr().first; + if(helpers::IsTranspose(k_pre)) { + k_pre = k_pre->inputs().at(0)->expr().first; + } + z = GetFmhaV2BlockCommonNode(k_pre); + if (z == nullptr) { + return false; + } + + if (mNumHeads != GetFmhaV2NumHeads(z)) { + return false; + } + node_k = z->inputs().at(0)->expr().first; + // whether mul(scale) + if (helpers::IsBinaryMul(node_k)) { + node_k = node_k->inputs().at(0)->expr().first; + } + + if (!helpers::IsMatMul(node_k)) { + return false; + } + + // whether slice + if (helpers::IsSlice(q_pre)) { + q_pre = q_pre->inputs().at(0)->expr().first; + } + z = GetFmhaV2BlockCommonNode(q_pre); + if (z == nullptr) { + return false; + } + if (mNumHeads != GetFmhaV2NumHeads(z)) { + return false; + } + node_q = z->inputs().at(0)->expr().first; + if (!helpers::IsMatMul(node_q)) { + return false; + } + + // QKV -> one source + if (node_q->inputs().at(0)->expr().first != node_k->inputs().at(0)->expr().first || node_q->inputs().at(0)->expr().first != node_v->inputs().at(0)->expr().first) { + return false; + } + fmha_v2_input_ = node_q->inputs().at(0); + var_q_weight = node_q->inputs().at(1); + var_k_weight = node_k->inputs().at(1); + var_v_weight = node_v->inputs().at(1); + + if(!helpers::IsConstant(var_q_weight->expr().first) || !helpers::IsConstant(var_k_weight->expr().first) || !helpers::IsConstant(var_v_weight->expr().first)) { + return false; + } + return true; + }; + + auto fold = [this](EXPRP expr) -> bool { + auto config = Global::Get(); + auto version = config->targetVersion; + if (version < 2.8f) { + // For target version < 2.8 , don't support fmha_v2 + return false; + } + + auto* var_q_weight_info = var_q_weight->getInfo(); + auto* var_k_weight_info = var_k_weight->getInfo(); + auto* var_v_weight_info = var_v_weight->getInfo(); + + if (!var_q_weight_info || !var_k_weight_info || !var_v_weight_info || var_q_weight_info->size != var_k_weight_info->size || var_q_weight_info->size != var_v_weight_info->size) { + return false; + } + int size = var_q_weight_info->size; + int C = var_q_weight_info->dim[0]; + int H = mNumHeads; + int D = var_q_weight_info->dim[1] / H; + if (var_q_weight_info->dim[1] % H != 0) { + return false; + } + + // FuseQKV_Weight + /* [C, H, D] -> [C, H, 3, D]*/ + auto output = _MatMul(fmha_v2_input_, _Reshape(_Concat({_Reshape(var_q_weight, {C, H, D}), _Reshape(var_k_weight, {C, H, D}), _Reshape(var_v_weight, {C, H, D})}, -1), {C, H*3*D}), false, false); + + std::unique_ptr param_fmha(new MNN::FmhaV2ParamT); + param_fmha->heads = mNumHeads; + + std::unique_ptr fmha_v2_op(new OpT); + fmha_v2_op->name = "FmhaV2_" + expr->name(); + fmha_v2_op->type = OpType_FmhaV2; + fmha_v2_op->main.type = OpParameter_FmhaV2Param; + fmha_v2_op->main.value = param_fmha.release(); + + auto fmha_v2_expr = Variable::create(Expr::create(fmha_v2_op.get(), { output }, 1)); + + fmha_v2_expr->setName(expr->name()); + Expr::replace(expr, fmha_v2_expr->expr().first); + return true /*modified*/; + }; + TemplateMerge::getInstance("Merge").insertTemplate("FuseSelfAttentionV2", match, fold); +} + class FuseSelfFmhaV2 { public: @@ -384,6 +630,7 @@ FuseSelfFmhaV2::FuseSelfFmhaV2() { static FuseFmhaV2 g_fuse_fmhaV2; static FuseSelfFmhaV2 g_fuse_self_fmhaV2; +static FuseSelfAttentionV2 g_fuse_self_attentionV2; } // namespace Express } // namespace MNN diff --git a/tools/converter/source/optimizer/merge/FuseGroupNorm.cpp b/tools/converter/source/optimizer/merge/FuseGroupNorm.cpp index 58d9378cb..77ff1cabf 100644 --- a/tools/converter/source/optimizer/merge/FuseGroupNorm.cpp +++ b/tools/converter/source/optimizer/merge/FuseGroupNorm.cpp @@ -30,6 +30,7 @@ class FuseGroupNormWithSwish { bool mHasPrefixAdd = false; VARP gamma_var_; VARP beta_var_; + EXPRP mGroupNorm; int mGroup; }; @@ -42,6 +43,9 @@ bool IsSigmoid(EXPRP expr) { if (op->type() == OpType_Sigmoid) { return true; } + if (op->type() == OpType_UnaryOp && op->main_as_UnaryOp()->opType() == UnaryOpOperation_SIGMOID) { + return true; + } return false; } bool IsLayerNorm(EXPRP expr) { @@ -54,12 +58,12 @@ bool IsLayerNorm(EXPRP expr) { } return false; } -bool IsGroupNorm(EXPRP expr) { +bool IsGroupNormNoSwish(EXPRP expr) { const Op* op = expr->get(); if (op == nullptr) { return false; } - if (op->type() == OpType_GroupNorm) { + if (op->type() == OpType_GroupNorm && op->main_as_GroupNorm()->bSwish() == 0) { return true; } return false; @@ -80,19 +84,16 @@ bool FuseGroupNormWithSwish::match_group_norm(EXPRP expr, bool testSwish) { // mul x = expr->inputs().at(0)->expr().first; y = expr->inputs().at(1)->expr().first; - if (helpers::IsBinaryAdd(x) && IsSigmoid(y) && (x == y->inputs().at(0)->expr().first)) { + if (IsGroupNormNoSwish(x) && IsSigmoid(y) && (x == y->inputs().at(0)->expr().first)) { z = x; - } else if (helpers::IsBinaryAdd(y) && IsSigmoid(x) && (y == x->inputs().at(0)->expr().first)) { + } else if (IsGroupNormNoSwish(y) && IsSigmoid(x) && (y == x->inputs().at(0)->expr().first)) { z = y; } else { return false; } mSwish = 1; - // cast - x = z->inputs().at(0)->expr().first; - if (helpers::IsCast(x)) { - z = x; - } + mGroupNorm = z; + return true; } else if (!testSwish && helpers::IsBinaryAdd(expr)) { z = expr; @@ -178,6 +179,31 @@ bool FuseGroupNormWithSwish::fold_group_norm(EXPRP expr, bool testSwish) { } std::unique_ptr group_norm(new MNN::GroupNormT); + + if(mSwish) { + auto gn = mGroupNorm->get()->main_as_GroupNorm(); + group_norm->epsilon = gn->epsilon(); + group_norm->bSwish = 1; + group_norm->group = gn->group(); + + int size = gn->gamma()->size(); + group_norm->gamma.resize(size); + group_norm->beta.resize(size); + memcpy(group_norm->gamma.data(), gn->gamma()->data(), size * sizeof(float)); + memcpy(group_norm->beta.data(), gn->beta()->data(), size * sizeof(float)); + + std::unique_ptr group_norm_op(new OpT); + group_norm_op->name = mGroupNorm->name(); + group_norm_op->type = OpType_GroupNorm; + group_norm_op->main.type = OpParameter_GroupNorm; + group_norm_op->main.value = group_norm.release(); + + auto group_norm_expr = Variable::create(Expr::create(group_norm_op.get(), mGroupNorm->inputs(), 1)); + group_norm_expr->setName("GroupNorm_" + expr->name()); + Expr::replace(expr, group_norm_expr->expr().first); + return true /*modified*/; + } + group_norm->epsilon = mEpsilon; group_norm->bSwish = mSwish; group_norm->group = mGroup; diff --git a/tools/converter/source/optimizer/merge/FuseSplitGeLu.cpp b/tools/converter/source/optimizer/merge/FuseSplitGeLu.cpp index c7a331c10..55ef9f0b5 100644 --- a/tools/converter/source/optimizer/merge/FuseSplitGeLu.cpp +++ b/tools/converter/source/optimizer/merge/FuseSplitGeLu.cpp @@ -52,8 +52,20 @@ FuseSplitGeLu::FuseSplitGeLu() { y = expr->inputs().at(1)->expr().first; if (helpers::IsBinaryMul(x) && helpers::IsSlice(y)) { z = x; + if(!helpers::IsConstant(y->inputs().at(1)->expr().first) || y->inputs().at(1)->readMap()[0] != 0) { + return false; + } + if(!helpers::IsConstant(y->inputs().at(3)->expr().first) || y->inputs().at(3)->readMap()[0] != -1) { + return false; + } } else if (helpers::IsBinaryMul(y) && helpers::IsSlice(x)) { z = y; + if(!helpers::IsConstant(x->inputs().at(1)->expr().first) || x->inputs().at(1)->readMap()[0] != 0) { + return false; + } + if(!helpers::IsConstant(x->inputs().at(3)->expr().first) || x->inputs().at(3)->readMap()[0] != -1) { + return false; + } } else { return false; } @@ -108,22 +120,35 @@ FuseSplitGeLu::FuseSplitGeLu() { } // slice x = z->inputs().at(0)->expr().first; - + auto res = z; mHasPrefixAdd = false; if (helpers::IsBinaryAdd(x)) { z = x; x = z->inputs().at(0)->expr().first; y = z->inputs().at(1)->expr().first; if (helpers::IsConstant(x)){ - split_gelu_input_0 = z->inputs().at(1); - split_gelu_input_1 = z->inputs().at(0); + if(z->inputs().at(0)->getInfo()->dim.size() == 1) { + split_gelu_input_0 = z->inputs().at(1); + split_gelu_input_1 = z->inputs().at(0); + } else { + split_gelu_input_0 = res->inputs().at(0); + return true; + } + } else if (helpers::IsConstant(y)){ + if(z->inputs().at(1)->getInfo()->dim.size() == 1) { + split_gelu_input_0 = z->inputs().at(0); + split_gelu_input_1 = z->inputs().at(1); + } else { + split_gelu_input_0 = res->inputs().at(0); + return true; + } } else { - split_gelu_input_0 = z->inputs().at(0); - split_gelu_input_1 = z->inputs().at(1); + split_gelu_input_0 = res->inputs().at(0); + return true; } mHasPrefixAdd = true; } else { - split_gelu_input_0 = z->inputs().at(0); + split_gelu_input_0 = res->inputs().at(0); } return true; }; diff --git a/tools/converter/source/optimizer/onnxextra/ResolveIdentityOnnx.cpp b/tools/converter/source/optimizer/onnxextra/ResolveIdentityOnnx.cpp deleted file mode 100644 index 3d202bcb1..000000000 --- a/tools/converter/source/optimizer/onnxextra/ResolveIdentityOnnx.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// ResolveIdentityOnnx.cpp -// MNNConverter -// -// Created by MNN on 2019/10/24. -// Copyright © 2018, Alibaba Group Holding Limited -// - -#include "MNN_generated.h" -#include "OnnxExtraManager.hpp" - -namespace MNN { -namespace Express { - -class ResolveIdentityOnnx : public OnnxExtraManager::Transform { -public: - virtual EXPRP onExecute(EXPRP expr) const override { - auto inputs = expr->inputs(); - MNN_THROW_CHECK(inputs.size() == 1, "Identity Should have one input"); - - auto outputs = expr->outputs(); - MNN_THROW_CHECK(outputs.size() == 1, "Identity Should have one output"); - auto outputVaribale = outputs.front(); - - auto outputExpr = outputVaribale.lock(); - auto outputExprOp = outputExpr->get(); - - std::unique_ptr newOp(new OpT); - newOp->name = outputExprOp->name()->str(); - newOp->type = outputExprOp->type(); - newOp->main.type = outputExprOp->main_type(); - newOp->main.value = const_cast(outputExprOp->main()); - - auto outputExprInputs = outputExpr->inputs(); - - // find the matched input, then replace it - const int size = outputExprInputs.size(); - for (int i = 0; i < size; ++i) { - if (outputExprInputs[i]->expr().first.get() == outputExpr.get()) { - outputExprInputs[i] = inputs[0]; - break; - } - } - return Expr::create(newOp.get(), outputExprInputs); - } -}; - -static auto gRegister = []() { - OnnxExtraManager::get()->insert("Dropout", std::shared_ptr(new ResolveIdentityOnnx)); - - OnnxExtraManager::get()->insert("Identity", std::shared_ptr(new ResolveIdentityOnnx)); - return true; -}(); - -} // namespace Express -} // namespace MNN diff --git a/tools/converter/source/optimizer/postconvert/MergeBNToConvolution.cpp b/tools/converter/source/optimizer/postconvert/MergeBNToConvolution.cpp index 2cfbfd13c..73aaa04c3 100644 --- a/tools/converter/source/optimizer/postconvert/MergeBNToConvolution.cpp +++ b/tools/converter/source/optimizer/postconvert/MergeBNToConvolution.cpp @@ -53,13 +53,18 @@ class MergeBNToConvolution : public MergeToConvolution { if (convolutionOp->type == OpType_Deconvolution) { int inputCount = conv2D->weight.size() / outputCount / conv2D->common->kernelX / conv2D->common->kernelY; - for (int i = 0; i < inputCount; ++i) { - auto dstPos = i * outputCount * conv2D->common->kernelY * conv2D->common->kernelX; - for (int j = 0; j < outputCount; ++j) { - auto dstPosJ = dstPos + j * conv2D->common->kernelY * conv2D->common->kernelX; - float a = alpha[j]; - for (int k = 0; k < conv2D->common->kernelY * conv2D->common->kernelX; ++k) { - conv2D->weight[dstPosJ + k] *= a; + int suboutputCount = outputCount / convCommon->group; + for (int g=0; ggroup; ++g) { + auto alpg = alpha.data() + g * suboutputCount; + auto wOffset = conv2D->weight.size() / convCommon->group * g; + for (int i = 0; i < inputCount; ++i) { + auto dstPos = i * suboutputCount * conv2D->common->kernelY * conv2D->common->kernelX; + for (int j = 0; j < suboutputCount; ++j) { + auto dstPosJ = dstPos + j * conv2D->common->kernelY * conv2D->common->kernelX; + float a = alpg[j]; + for (int k = 0; k < conv2D->common->kernelY * conv2D->common->kernelX; ++k) { + conv2D->weight[dstPosJ + k + wOffset] *= a; + } } } } diff --git a/tools/converter/source/optimizer/postconvert/MergeScaleToConvolution.cpp b/tools/converter/source/optimizer/postconvert/MergeScaleToConvolution.cpp index 9b3d219cd..d1409ca01 100644 --- a/tools/converter/source/optimizer/postconvert/MergeScaleToConvolution.cpp +++ b/tools/converter/source/optimizer/postconvert/MergeScaleToConvolution.cpp @@ -6,6 +6,7 @@ // Copyright © 2018, Alibaba Group Holding Limited // +#include #include "../PostTreatUtils.hpp" #include "MergeToConvolution.hpp" @@ -41,13 +42,18 @@ class MergeScaleToConvolution : public MergeToConvolution { if (convolutionOp->type == OpType_Deconvolution) { int inputCount = conv2D->weight.size() / outputCount / conv2D->common->kernelX / conv2D->common->kernelY; - for (int i = 0; i < inputCount; ++i) { - auto dstPos = i * outputCount * conv2D->common->kernelY * conv2D->common->kernelX; - for (int j = 0; j < outputCount; ++j) { - auto dstPosJ = dstPos + j * conv2D->common->kernelY * conv2D->common->kernelX; - float a = alpha[j]; - for (int k = 0; k < conv2D->common->kernelY * conv2D->common->kernelX; ++k) { - conv2D->weight[dstPosJ + k] *= a; + int suboutputCount = outputCount / convCommon->group; + for (int g=0; ggroup; ++g) { + auto alpg = alpha.data() + g * suboutputCount; + auto wOffset = conv2D->weight.size() / convCommon->group * g; + for (int i = 0; i < inputCount; ++i) { + auto dstPos = i * suboutputCount * conv2D->common->kernelY * conv2D->common->kernelX; + for (int j = 0; j < suboutputCount; ++j) { + auto dstPosJ = dstPos + j * conv2D->common->kernelY * conv2D->common->kernelX; + float a = alpg[j]; + for (int k = 0; k < conv2D->common->kernelY * conv2D->common->kernelX; ++k) { + conv2D->weight[dstPosJ + k + wOffset] *= a; + } } } } diff --git a/tools/converter/source/optimizer/postconvert/MergeToConvolution.hpp b/tools/converter/source/optimizer/postconvert/MergeToConvolution.hpp index 80f1b1139..24bc2251a 100644 --- a/tools/converter/source/optimizer/postconvert/MergeToConvolution.hpp +++ b/tools/converter/source/optimizer/postconvert/MergeToConvolution.hpp @@ -6,6 +6,7 @@ // Copyright © 2018, Alibaba Group Holding Limited // +#include #include "../PostTreatUtils.hpp" using namespace MNN; @@ -18,6 +19,10 @@ class MergeToConvolution : public PostConverter { virtual bool onExecute(std::unique_ptr& net) const override { // Merge Layer std::vector readyToDelete; + std::set outputNames; + for (auto n : net->outputName) { + outputNames.insert(n); + } for (auto iter = net->oplists.begin(); iter != net->oplists.end(); iter++) { MNN::OpT& currentOp = *(iter->get()); if (currentOp.type != MNN::OpType_Convolution @@ -27,6 +32,9 @@ class MergeToConvolution : public PostConverter { continue; } DCHECK(currentOp.outputIndexes.size() == 1) << "Conv output ERROR!"; + if (outputNames.find(net->tensorName[currentOp.outputIndexes[0]]) != outputNames.end()) { + continue; + } // merge Batchnorm/Relu/Relu6 to Convolution std::vector nextOp = PostTreatUtils::_findOpByInputIndex(currentOp.outputIndexes[0], net.get()); diff --git a/tools/converter/source/optimizer/postconvert/TransformGroupConvolution.cpp b/tools/converter/source/optimizer/postconvert/TransformGroupConvolution.cpp index 0e42c5769..1c5498e26 100644 --- a/tools/converter/source/optimizer/postconvert/TransformGroupConvolution.cpp +++ b/tools/converter/source/optimizer/postconvert/TransformGroupConvolution.cpp @@ -6,6 +6,7 @@ // Copyright © 2018, Alibaba Group Holding Limited // +#include #include "../PostTreatUtils.hpp" using namespace MNN; class TransformGroupConvolution3D : public PostConverter { @@ -227,6 +228,9 @@ class TransformGroupConvolution : public PostConverter { int partBiasSize = conv2D->bias.size() / common->group; // Create Sub Convolution + flatbuffers::FlatBufferBuilder tmpBuilder; + tmpBuilder.Finish(Convolution2DCommon::Pack(tmpBuilder, common.get())); + auto originCommon = flatbuffers::GetRoot(tmpBuilder.GetBufferPointer()); for (int i = 0; i < common->group; ++i) { std::ostringstream opNameOs; auto newConvOp = new MNN::OpT; @@ -239,23 +243,10 @@ class TransformGroupConvolution : public PostConverter { auto newConvolutionT = new MNN::Convolution2DT; newConvOp->main.value = newConvolutionT; - newConvolutionT->common = std::unique_ptr(new MNN::Convolution2DCommonT); - newConvolutionT->common->kernelX = common->kernelX; - newConvolutionT->common->kernelY = common->kernelY; - newConvolutionT->common->dilateY = common->dilateY; - newConvolutionT->common->dilateX = common->dilateX; - newConvolutionT->common->strideX = common->strideX; - newConvolutionT->common->strideY = common->strideY; + newConvolutionT->common = std::unique_ptr(originCommon->UnPack()); newConvolutionT->common->group = 1; - newConvolutionT->common->padMode = common->padMode; newConvolutionT->common->outputCount = common->outputCount / common->group; newConvolutionT->common->inputCount = common->inputCount / common->group; - newConvolutionT->common->padX = common->padX; - newConvolutionT->common->padY = common->padY; - newConvolutionT->common->relu = common->relu; - newConvolutionT->common->relu6 = common->relu6; - newConvolutionT->common->outPads = common->outPads; - int startWeight = partWeightSize * i; int startBias = partBiasSize * i; for (int v = 0; v < partWeightSize; ++v) { diff --git a/tools/cpp/ExprDebug.hpp b/tools/cpp/ExprDebug.hpp index ce342a0dd..2b5688d58 100644 --- a/tools/cpp/ExprDebug.hpp +++ b/tools/cpp/ExprDebug.hpp @@ -242,7 +242,7 @@ static void _initTensorStatic() { continue; } auto data = res.second; - MNN_PRINT("%s [Input] %s_%d, Max: %f, Min: %f, Avg: %f, [", info->type().c_str(), opName.c_str(), i, std::get<0>(data), std::get<1>(data), std::get<2>(data)); + MNN_PRINT("%s [Input] %s_%d, type:%d-%d, Max: %f, Min: %f, Avg: %f, [", info->type().c_str(), opName.c_str(), i, ntensor->getType().code, ntensor->getType().bits, std::get<0>(data), std::get<1>(data), std::get<2>(data)); for (int v=0; vdimensions(); ++v) { MNN_PRINT("%d", ntensor->length(v)); if (v!=ntensor->dimensions()-1) { @@ -265,7 +265,7 @@ static void _initTensorStatic() { continue; } auto data = res.second; - MNN_PRINT("%s [Output] %s_%d, Max: %f, Min: %f, Avg: %f, [", info->type().c_str(), opName.c_str(), i, std::get<0>(data), std::get<1>(data), std::get<2>(data)); + MNN_PRINT("%s [Output] %s_%d, type:%d-%d, Max: %f, Min: %f, Avg: %f, [", info->type().c_str(), opName.c_str(), i, ntensor->getType().code, ntensor->getType().bits, std::get<0>(data), std::get<1>(data), std::get<2>(data)); for (int v=0; vdimensions(); ++v) { MNN_PRINT("%d", ntensor->length(v)); if (v!=ntensor->dimensions()-1) { diff --git a/tools/cpp/testModel.cpp b/tools/cpp/testModel.cpp index 6f7d819f4..30d2d5c2c 100644 --- a/tools/cpp/testModel.cpp +++ b/tools/cpp/testModel.cpp @@ -79,6 +79,7 @@ int main(int argc, const char* argv[]) { if (argc > 6) { precision = (MNN::BackendConfig::PrecisionMode)stringConvert(argv[6]); } + std::shared_ptr net = std::shared_ptr(MNN::Interpreter::createFromFile(modelPath), [](void* net) { MNN::Interpreter::destroy((MNN::Interpreter*)net); diff --git a/tools/cv/source/imgcodecs/imgcodecs.cpp b/tools/cv/source/imgcodecs/imgcodecs.cpp index 04d577dcb..83a83ecd5 100644 --- a/tools/cv/source/imgcodecs/imgcodecs.cpp +++ b/tools/cv/source/imgcodecs/imgcodecs.cpp @@ -18,7 +18,7 @@ #define STBI_ONLY_PNG #define STBI_ONLY_BMP #define STB_IMAGE_STATIC - +#define STB_IMAGE_WRITE_STATIC #include "stb_image.h" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" diff --git a/tools/quantization/Helper.cpp b/tools/quantization/Helper.cpp index 487ebb9b9..9bbd29934 100644 --- a/tools/quantization/Helper.cpp +++ b/tools/quantization/Helper.cpp @@ -59,7 +59,7 @@ void Helper::readClibrationFiles(std::vector& images, const std::st continue; } const std::string fileName = filePath + "\\" + ffd.cFileName; - if (INVALID_FILE_ATTRIBUTES != GetFileAttributes(fileName.c_str()) && GetLastError() != ERROR_FILE_NOT_FOUND) { + if (INVALID_FILE_ATTRIBUTES != GetFileAttributes(fileName.c_str()) && FILE_ATTRIBUTE_DIRECTORY) { if (*usedImageNum == 0) { // use all images in the folder images.push_back(fileName); @@ -73,6 +73,22 @@ void Helper::readClibrationFiles(std::vector& images, const std::st else { break; } + } else { + if (INVALID_FILE_ATTRIBUTES != GetFileAttributes(fileName.c_str()) && GetLastError() != ERROR_FILE_NOT_FOUND) { + if (*usedImageNum == 0) { + // use all images in the folder + images.push_back(fileName); + count++; + } + else if (count < *usedImageNum) { + // use usedImageNum images + images.push_back(fileName); + count++; + } + else { + break; + } + } } } @@ -83,13 +99,13 @@ void Helper::readClibrationFiles(std::vector& images, const std::st MNN_ERROR("open %s failed!\n", filePath.c_str()); return; } + struct stat s; struct dirent* ent = readdir(root); while (ent != NULL) { if (ent->d_name[0] != '.') { - const std::string fileName = filePath + "/" + ent->d_name; - if (fileExist(fileName)) { - // std::cout << "==> " << fileName << std::endl; - // DLOG(INFO) << fileName; + const std::string fileName = filePath + ent->d_name; + stat(fileName.c_str(), &s); + if (s.st_mode & S_IFDIR) { if (*usedImageNum == 0) { // use all images in the folder images.push_back(fileName); @@ -101,6 +117,22 @@ void Helper::readClibrationFiles(std::vector& images, const std::st } else { break; } + } else { + if (fileExist(fileName)) { + // std::cout << "==> " << fileName << std::endl; + // DLOG(INFO) << fileName; + if (*usedImageNum == 0) { + // use all images in the folder + images.push_back(fileName); + count++; + } else if (count < *usedImageNum) { + // use usedImageNum images + images.push_back(fileName); + count++; + } else { + break; + } + } } } ent = readdir(root); @@ -108,11 +140,10 @@ void Helper::readClibrationFiles(std::vector& images, const std::st #endif *usedImageNum = images.size(); - DLOG(INFO) << "used image num: " << images.size(); + DLOG(INFO) << "used dataset num: " << images.size(); } -void Helper::preprocessInput(MNN::CV::ImageProcess* pretreat, PreprocessConfig preprocessConfig, - const std::string& filename, MNN::Tensor* input, InputType inputType) { +void Helper::preprocessInput(MNN::CV::ImageProcess* pretreat, PreprocessConfig preprocessConfig, const std::string& filename, MNN::Tensor* input, InputType inputType) { if (inputType == InputType::IMAGE) { int originalWidth, originalHeight, comp; auto bitmap32bits = stbi_load(filename.c_str(), &originalWidth, &originalHeight, &comp, 4); diff --git a/tools/quantization/TensorStatistic.cpp b/tools/quantization/TensorStatistic.cpp index 734fa1a92..fad617d31 100644 --- a/tools/quantization/TensorStatistic.cpp +++ b/tools/quantization/TensorStatistic.cpp @@ -12,6 +12,7 @@ #include #include #include "logkit.h" +#include "core/TensorUtils.hpp" // Given distribution P and Q, KL-Divergence is // Sum(P[i] * log(P[i] / Q[i])) @@ -53,30 +54,21 @@ void TensorStatistic::updateRange() { return; } mUpdatedRangeFlags = true; - mOriginTensor->copyToHostTensor(mHostTensor.get()); - int batch = mHostTensor->batch(); - int channel = mHostTensor->channel(); - int width = mHostTensor->width(); - int height = mHostTensor->height(); - auto area = width * height; - if (area == 0) { - area = 1; + auto tmpTensor = mOriginTensor; + bool res = mOriginTensor->copyToHostTensor(mHostTensor.get()); + if (res) { + tmpTensor = mHostTensor.get(); } - - for (int n = 0; n < batch; ++n) { - auto dataBatch = mHostTensor->host() + n * mHostTensor->stride(0); - for (int c = 0; c < channel; ++c) { - auto minValue = mRange.first; - auto maxValue = mRange.second; - auto dataChannel = dataBatch + c * mHostTensor->stride(1); - for (int v = 0; v < area; ++v) { - minValue = std::min(minValue, dataChannel[v]); - maxValue = std::max(maxValue, dataChannel[v]); - } - mRange.first = minValue; - mRange.second = maxValue; - } + int size = tmpTensor->elementSize(); + float* dataPtr = tmpTensor->host(); + auto minValue = mRange.first; + auto maxValue = mRange.second; + for (int i = 0; i < size; ++i) { + minValue = std::min(minValue, dataPtr[i]); + maxValue = std::max(maxValue, dataPtr[i]); } + mRange.first = minValue; + mRange.second = maxValue; // if (mRange.first > 0.0f) { // mRange.first = 0.0f; // } @@ -102,36 +94,22 @@ void TensorStatistic::updateDistribution() { return; } mUpdatedDistributionFlag = true; - mOriginTensor->copyToHostTensor(mHostTensor.get()); - int batch = mHostTensor->batch(); - int channel = mHostTensor->channel(); - int width = mHostTensor->width(); - int height = mHostTensor->height(); - auto area = width * height; - if (area == 0) { - area = 1; + auto tmpTensor = mOriginTensor; + bool res = mOriginTensor->copyToHostTensor(mHostTensor.get()); + if (res) { + tmpTensor = mHostTensor.get(); } // float midValue = (mRange.second + mRange.first) / 2.0f; float midValue = 0.f; - for (int n = 0; n < batch; ++n) { - auto dataBatch = mHostTensor->host() + n * mHostTensor->stride(0); - for (int c = 0; c < channel; ++c) { - if (!mValid) { - continue; - } - auto multi = mInterval; - auto target = mDistribution.data(); - auto dataChannel = dataBatch + c * mHostTensor->stride(1); - for (int v = 0; v < area; ++v) { - auto data = dataChannel[v] - midValue; - if (data == 0) { - continue; - } - int index = static_cast(fabs(data) * multi); - index = std::min(index, mBinNumber - 1); - target[index] += 1.0f; - } + auto ptr = tmpTensor->host(); + for (int i = 0; i < tmpTensor->elementSize(); ++i) { + auto data = ptr[i] - midValue; + if (abs(data) <= 1e-6) { + continue; } + int index = static_cast(fabs(data) * mInterval); + index = std::min(index, mBinNumber - 1); + mDistribution[index] += 1.0f; } } diff --git a/tools/quantization/calibration.cpp b/tools/quantization/calibration.cpp index 32d13aaad..4ae33f3d8 100644 --- a/tools/quantization/calibration.cpp +++ b/tools/quantization/calibration.cpp @@ -39,12 +39,159 @@ #include "core/ConvolutionCommon.hpp" #include + +#include +#include +#define DUMP_NUM_DATA(type) \ + auto data = tensor->host(); \ + for (int z = 0; z < outside; ++z) { \ + for (int x = 0; x < width; ++x) { \ + outputOs << data[x + z * width] << "\t"; \ + } \ + outputOs << "\n"; \ + } + +#define DUMP_CHAR_DATA(type) \ + auto data = tensor->host(); \ + for (int z = 0; z < outside; ++z) { \ + for (int x = 0; x < width; ++x) { \ + outputOs << static_cast(data[x + z * width]) << "\t"; \ + } \ + outputOs << "\n"; \ + } + +static void dumpTensor2File(const Tensor* tensor, const char* file) { + std::ofstream outputOs(file); + auto type = tensor->getType(); + + int dimension = tensor->buffer().dimensions; + int width = 1; + if (dimension > 1) { + width = tensor->length(dimension - 1); + } + + const int outside = tensor->elementSize() / width; + + const auto dataType = type.code; + const auto dataBytes = type.bytes(); + + if (dataType == halide_type_float) { + DUMP_NUM_DATA(float); + } + if (dataType == halide_type_int && dataBytes == 4) { + DUMP_NUM_DATA(int32_t); + } + if (dataType == halide_type_uint && dataBytes == 1) { + DUMP_CHAR_DATA(uint8_t); + } + if (dataType == halide_type_int && dataBytes == 1) { +#ifdef MNN_USE_SSE + auto data = tensor->host(); + for (int z = 0; z < outside; ++z) { + for (int x = 0; x < width; ++x) { + outputOs << (static_cast(data[x + z * width]) - 128) << "\t"; + } + outputOs << "\n"; + } +#else + DUMP_CHAR_DATA(int8_t); +#endif + } +} + using namespace MNN::CV; using namespace MNN::Train; using namespace MNN::Express; -Calibration::Calibration(MNN::NetT* model, const uint8_t* modelBuffer, const int bufferSize, const std::string& configPath, std::string originalModelFile, std::string destModelFile) - : _originalModel(model), _originalModelFile(originalModelFile), _destModelFile(destModelFile) { +static std::vector getModuleInputs(std::string file, const Module::Info* netInfo, std::vector inputNames, std::map> inputShape) { +#define LOAD_DATA(TYPE)\ +std::ostringstream fileNameOs;\ +fileNameOs << file << "/" << inputName << ".txt";\ +auto fileName = fileNameOs.str();\ +std::ifstream inputOs(fileName.c_str());\ +if (inputOs.fail()) {\ +MNN_ERROR("TESTERROR Can't open %s\n", fileName.c_str());\ +continue;\ +}\ +for (int i=0; isize; ++i) {\ +double tempValue;\ +inputOs >> tempValue;\ +ptr[i] = tempValue;\ +}\ + +#define LOAD_DATA_SHAPE() \ +std::ostringstream file_name_os;\ +file_name_os << file << "/input.json";\ +auto file_name = file_name_os.str();\ +std::ifstream input_os(file_name.c_str());\ +if (input_os.fail()) {\ +MNN_PRINT("input.json does not exit in %s, use default shape.\n", file.c_str());\ +dyInputShape=inputShape;\ +} else {\ +rapidjson::Document document;\ +std::ostringstream json_os;\ +json_os << input_os.rdbuf();\ +document.Parse(json_os.str().c_str());\ +if (document.HasParseError()) {\ +MNN_ERROR("Invalid json: %s\n", file_name.c_str());\ +}\ +auto cfgObj = document.GetObject();\ +if (cfgObj.HasMember("inputs")) {\ +auto inputsInfo = document["inputs"].GetArray();\ +for (auto iter = inputsInfo.begin(); iter !=inputsInfo.end(); iter++) {\ +auto obj = iter->GetObject();\ +std::string name = obj["name"].GetString();\ +if (obj.HasMember("shape")) {\ +auto dims = obj["shape"].GetArray();\ +std::vector shapes;\ +for (auto iter = dims.begin(); iter != dims.end(); iter++) {\ + shapes.emplace_back(iter->GetInt());\ +}\ +dyInputShape.insert(std::make_pair(name, shapes));\ +}\ +}\ +}\ +else {\ +MNN_ERROR("input.json must have inputs infomation!\n");\ +}\ +}\ + + std::vector inputs; + inputs.resize(netInfo->inputs.size()); + for (int i=0; iinputs[i].dim, netInfo->inputs[i].order, netInfo->inputs[i].type); + } + // Load inputs + std::map> dyInputShape; + LOAD_DATA_SHAPE() + for (int i=0; isecond; + inputs[i] = _Input(s, netInfo->defaultFormat, netInfo->inputs[i].type); + } + auto info = inputs[i]->getInfo(); + if (info->type == halide_type_of()){ + auto ptr = inputs[i]->writeMap(); + LOAD_DATA(float) + } else { + auto floatVar = _Input(info->dim, info->order, halide_type_of()); + auto ptr = floatVar->writeMap(); + LOAD_DATA(float) + auto temp = _Cast(floatVar, info->type); + inputs[i]->input(temp); + } + inputs[i] = _Convert(inputs[i], netInfo->inputs[i].order); + } + +#undef LOAD_DATA +#undef LOAD_DATA_SHAPE + return inputs; +} + +Calibration::Calibration(MNN::NetT* model, const uint8_t* modelBuffer, const int bufferSize, const std::string& configPath, std::string originalModelFile, std::string destModelFile) : _originalModel(model), _originalModelFile(originalModelFile), _destModelFile(destModelFile) { // when the format of input image is RGB/BGR, channels equal to 3, GRAY is 1 _channels = 3; @@ -92,124 +239,182 @@ Calibration::Calibration(MNN::NetT* model, const uint8_t* modelBuffer, const int _imageProcessConfig.sourceFormat = RGBA; _calibrationFileNum = 0; - { - if (picObj.HasMember("mean")) { - auto mean = picObj["mean"].GetArray(); - int cur = 0; - for (auto iter = mean.begin(); iter != mean.end(); iter++) { - _imageProcessConfig.mean[cur++] = iter->GetFloat(); - } - } - if (picObj.HasMember("normal")) { - auto normal = picObj["normal"].GetArray(); - int cur = 0; - for (auto iter = normal.begin(); iter != normal.end(); iter++) { - _imageProcessConfig.normal[cur++] = iter->GetFloat(); - } - } - if (picObj.HasMember("center_crop_h")) { - _preprocessConfig.centerCropHeight = picObj["center_crop_h"].GetFloat(); - } - if (picObj.HasMember("center_crop_w")) { - _preprocessConfig.centerCropWidth = picObj["center_crop_w"].GetFloat(); + + if (picObj.HasMember("mean")) { + auto mean = picObj["mean"].GetArray(); + int cur = 0; + for (auto iter = mean.begin(); iter != mean.end(); iter++) { + _imageProcessConfig.mean[cur++] = iter->GetFloat(); } - if (picObj.HasMember("width")) { - _width = picObj["width"].GetInt(); - _preprocessConfig.targetWidth = _width; - } - if (picObj.HasMember("height")) { - _height = picObj["height"].GetInt(); - _preprocessConfig.targetHeight = _height; + } + if (picObj.HasMember("normal")) { + auto normal = picObj["normal"].GetArray(); + int cur = 0; + for (auto iter = normal.begin(); iter != normal.end(); iter++) { + _imageProcessConfig.normal[cur++] = iter->GetFloat(); } - if (picObj.HasMember("batch_size")) { - _batch = picObj["batch_size"].GetInt(); + } + if (picObj.HasMember("center_crop_h")) { + _preprocessConfig.centerCropHeight = picObj["center_crop_h"].GetFloat(); + } + if (picObj.HasMember("center_crop_w")) { + _preprocessConfig.centerCropWidth = picObj["center_crop_w"].GetFloat(); + } + if (picObj.HasMember("width")) { + _width = picObj["width"].GetInt(); + _preprocessConfig.targetWidth = _width; + } + if (picObj.HasMember("height")) { + _height = picObj["height"].GetInt(); + _preprocessConfig.targetHeight = _height; + } + if (picObj.HasMember("batch_size")) { + _batch = picObj["batch_size"].GetInt(); + } + if (picObj.HasMember("quant_bits")) { + _quant_bits = picObj["quant_bits"].GetInt(); + } + if (!picObj.HasMember("path")) { + MNN_ERROR("calibration data path not set in .json config file\n"); + return; + } + _calibrationFilePath = picObj["path"].GetString(); + if (picObj.HasMember("used_image_num")) { + _calibrationFileNum = picObj["used_image_num"].GetInt(); + } + if (picObj.HasMember("used_sample_num")) { + _calibrationFileNum = picObj["used_sample_num"].GetInt(); + } + if (picObj.HasMember("feature_quantize_method")) { + std::string method = picObj["feature_quantize_method"].GetString(); + if (Helper::featureQuantizeMethod.find(method) != Helper::featureQuantizeMethod.end()) { + _featureQuantizeMethod = method; + } else { + MNN_ERROR("not supported feature quantization method: %s\n", method.c_str()); + return; } - if (picObj.HasMember("quant_bits")) { - _quant_bits = picObj["quant_bits"].GetInt(); + } + if (picObj.HasMember("weight_quantize_method")) { + std::string method = picObj["weight_quantize_method"].GetString(); + if (Helper::weightQuantizeMethod.find(method) != Helper::weightQuantizeMethod.end()) { + _weightQuantizeMethod = method; + } else { + MNN_ERROR("not supported weight quantization method: %s\n", method.c_str()); + return; } - if (!picObj.HasMember("path")) { - MNN_ERROR("calibration data path not set in .json config file\n"); + } + DLOG(INFO) << "Use feature quantization method: " << _featureQuantizeMethod; + DLOG(INFO) << "Use weight quantization method: " << _weightQuantizeMethod; + if (picObj.HasMember("feature_clamp_value")) { + float value = (int)picObj["feature_clamp_value"].GetFloat(); + if (value < 0.0f || value > 127.0f) { + MNN_ERROR("feature_clamp_value should be in (0, 127], got: %f\n", value); return; } - _calibrationFilePath = picObj["path"].GetString(); - if (picObj.HasMember("used_image_num")) { - _calibrationFileNum = picObj["used_image_num"].GetInt(); + _featureClampValue = value; + } + if (picObj.HasMember("weight_clamp_value")) { + float value = (int)picObj["weight_clamp_value"].GetFloat(); + if (value < 0.0f || value > 127.0f) { + MNN_ERROR("weight_clamp_value should be in (0, 127], got: %f\n", value); + return; } - if (picObj.HasMember("used_sample_num")) { - _calibrationFileNum = picObj["used_sample_num"].GetInt(); + _weightClampValue = value; + if (_quant_bits < 8) { + _weightClampValue = (float)(1 << (_quant_bits - 1)) - 1.0f; } - if (picObj.HasMember("feature_quantize_method")) { - std::string method = picObj["feature_quantize_method"].GetString(); - if (Helper::featureQuantizeMethod.find(method) != Helper::featureQuantizeMethod.end()) { - _featureQuantizeMethod = method; - } else { - MNN_ERROR("not supported feature quantization method: %s\n", method.c_str()); - return; - } + } + DLOG(INFO) << "feature_clamp_value: " << _featureClampValue; + DLOG(INFO) << "weight_clamp_value: " << _weightClampValue; + if (picObj.HasMember("winogradOpt") && picObj["winogradOpt"].GetBool() == true) { + if (_featureQuantizeMethod == "EMA") { + _winogradOpt = true; + } else { + DLOG(ERROR) << "winogradOpt only be available under EMA"; } - if (picObj.HasMember("weight_quantize_method")) { - std::string method = picObj["weight_quantize_method"].GetString(); - if (Helper::weightQuantizeMethod.find(method) != Helper::weightQuantizeMethod.end()) { - _weightQuantizeMethod = method; - } else { - MNN_ERROR("not supported weight quantization method: %s\n", method.c_str()); - return; - } + } + if (picObj.HasMember("skip_quant_op_names")) { + auto skip_quant_op_names = picObj["skip_quant_op_names"].GetArray(); + for (auto iter = skip_quant_op_names.begin(); iter != skip_quant_op_names.end(); iter++) { + std::string skip_quant_op_name = iter->GetString(); + _skip_quant_ops.emplace_back(skip_quant_op_name); + DLOG(INFO) << "skip quant op name: " << skip_quant_op_name; } - DLOG(INFO) << "Use feature quantization method: " << _featureQuantizeMethod; - DLOG(INFO) << "Use weight quantization method: " << _weightQuantizeMethod; - if (picObj.HasMember("feature_clamp_value")) { - float value = (int)picObj["feature_clamp_value"].GetFloat(); - if (value < 0.0f || value > 127.0f) { - MNN_ERROR("feature_clamp_value should be in (0, 127], got: %f\n", value); - return; - } - _featureClampValue = value; + } + if (picObj.HasMember("debug")) { + _debug = picObj["debug"].GetBool(); + } + _inputType = Helper::InputType::IMAGE; + if (picObj.HasMember("input_type")) { + std::string type = picObj["input_type"].GetString(); + if (type == "sequence") { + _inputType = Helper::InputType::SEQUENCE; } - if (picObj.HasMember("weight_clamp_value")) { - float value = (int)picObj["weight_clamp_value"].GetFloat(); - if (value < 0.0f || value > 127.0f) { - MNN_ERROR("weight_clamp_value should be in (0, 127], got: %f\n", value); - return; + } + + _module.reset(Module::load({}, {}, originalModelFile.c_str())); + auto moduleInfo = _module->getInfo(); + for (int i = 0; i < moduleInfo->inputNames.size(); ++i) { + mInputNames.emplace_back(moduleInfo->inputNames[i]); + } + for (int i = 0; i < moduleInfo->outputNames.size(); ++i) { + mOutputNames.emplace_back(moduleInfo->outputNames[i]); + } + bool checkOutput = false; + if (picObj.HasMember("inputs")) { + auto inputsInfo = document["inputs"].GetArray(); + for (auto iter = inputsInfo.begin(); iter !=inputsInfo.end(); iter++) { + auto obj = iter->GetObject(); + std::string name = obj["name"].GetString(); + MNN_PRINT("input: %s\n", name.c_str()); + if (obj.HasMember("value")) { + float value = obj["value"].GetFloat(); + mInputInfo.insert(std::make_pair(name, value)); } - _weightClampValue = value; - if (_quant_bits < 8) { - _weightClampValue = (float)(1 << (_quant_bits - 1)) - 1.0f; + if (obj.HasMember("shape")) { + auto dims = obj["shape"].GetArray(); + std::vector shapes; + for (auto iter = dims.begin(); iter != dims.end(); iter++) { + shapes.emplace_back(iter->GetInt()); + } + mInputShape.insert(std::make_pair(name, shapes)); } } - DLOG(INFO) << "feature_clamp_value: " << _featureClampValue; - DLOG(INFO) << "weight_clamp_value: " << _weightClampValue; - if (picObj.HasMember("winogradOpt") && picObj["winogradOpt"].GetBool() == true) { - if (_featureQuantizeMethod == "EMA") { - _winogradOpt = true; - } else { - DLOG(ERROR) << "winogradOpt only be available under EMA"; + } + if (!picObj.HasMember("inputs")) { // User do not provide input names and shapes. + if (mInputNames.size() > 1) { + MNN_ERROR("Error: Input names and shapes should provided in json file!\n"); + } + std::string name = mInputNames[0]; + auto shape = moduleInfo->inputs[0].dim; + auto dimensionFormat = moduleInfo->inputs[0].order; + if (dimensionFormat == NCHW || dimensionFormat == NC4HW4) { + if (shape.size() > 2) { + shape[2] = _preprocessConfig.targetHeight; } - } - if (picObj.HasMember("skip_quant_op_names")) { - auto skip_quant_op_names = picObj["skip_quant_op_names"].GetArray(); - for (auto iter = skip_quant_op_names.begin(); iter != skip_quant_op_names.end(); iter++) { - std::string skip_quant_op_name = iter->GetString(); - _skip_quant_ops.emplace_back(skip_quant_op_name); - DLOG(INFO) << "skip quant op name: " << skip_quant_op_name; + if (shape.size() > 3) { + shape[3] = _preprocessConfig.targetWidth; } - } - if (picObj.HasMember("debug")) { - _debug = picObj["debug"].GetBool(); - } - _inputType = Helper::InputType::IMAGE; - if (picObj.HasMember("input_type")) { - std::string type = picObj["input_type"].GetString(); - if (type == "sequence") { - _inputType = Helper::InputType::SEQUENCE; + } else { // NHWC + if (shape.size() > 1) { + shape[1] = _preprocessConfig.targetHeight; + } + if (shape.size() > 2) { + shape[2] = _preprocessConfig.targetWidth; } } + mInputShape.insert(std::make_pair(name, shape)); } + std::shared_ptr process(ImageProcess::create(_imageProcessConfig), ImageProcess::destroy); _process = process; // read images file names + if (_calibrationFilePath.back() != '/') { + _calibrationFilePath = _calibrationFilePath + "/"; + } Helper::readClibrationFiles(_calibrationFiles, _calibrationFilePath.c_str(), &_calibrationFileNum); + std::sort(_calibrationFiles.begin(), _calibrationFiles.end()); for (auto& op : _originalModel->oplists) { if (op->type == MNN::OpType_BatchNorm) { @@ -227,124 +432,46 @@ Calibration::Calibration(MNN::NetT* model, const uint8_t* modelBuffer, const int } } } - + + MNN::ScheduleConfig config; + config.backupType = MNN_FORWARD_CPU; + config.numThread = 1; + std::shared_ptr rtmgr(Executor::RuntimeManager::createRuntimeManager(config)); if (_featureQuantizeMethod == "KL" || _featureQuantizeMethod == "ADMM") { - _initMNNSession(modelBuffer, bufferSize); - _initMaps(); + rtmgr->setMode(Interpreter::Session_Debug); } -} - -std::vector Calibration::_getInputShape(std::string filename) { - std::vector inputShape; - if (_inputType == Helper::InputType::IMAGE) { - inputShape.resize(4); - auto inputTensorDataFormat = MNN::TensorUtils::getDescribe(_inputTensor)->dimensionFormat; - if (inputTensorDataFormat == MNN::MNN_DATA_FORMAT_NHWC) { - inputShape[0] = 1; - inputShape[1] = _height; - inputShape[2] = _width; - inputShape[3] = _channels; - } else { - inputShape[0] = 1; - inputShape[1] = _channels; - inputShape[2] = _height; - inputShape[3] = _width; - } + _module.reset(Module::load(mInputNames, mOutputNames, originalModelFile.c_str(), rtmgr)); // rtmgr.mode->debug + if (_debug) { + _moduleOrigin.reset(Module::load(mInputNames, mOutputNames, originalModelFile.c_str(), rtmgr)); // rtmgr.mode->debug } - if (_inputType == Helper::InputType::SEQUENCE) { - if (!Helper::stringEndWith(filename, ".txt")) { - MNN_ERROR("Error: only '.txt' files are supported for sequence input.\n"); - } - std::ifstream f(filename); - if (!f.is_open()) { - MNN_ERROR("open file %s failed.\n", filename.c_str()); - } - - std::string line; - _channels = 0; - while (std::getline(f, line)) { - std::stringstream ss(line); - float v; - int count = 0; - while (ss >> v) { - count++; - } - if (count > 0) { - _channels++; - _height = count; + if (_featureQuantizeMethod == "KL" || _featureQuantizeMethod == "ADMM") { + _initMNNSession(modelBuffer, bufferSize); + auto netInfo = _module->getInfo(); + if (_inputType == Helper::SEQUENCE) { + mInputs = getModuleInputs(_calibrationFiles[0], _module->getInfo(), mInputNames, mInputShape); + for (int i = 0; i < mInputs.size(); ++i) { + auto input = mInputs[i]; + auto name = mInputNames[i]; + std::string fileName = _calibrationFiles[0] + "/" + name + ".txt"; + auto inputTensor = (MNN::Tensor*)input->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, fileName, inputTensor, _inputType); } - } - - if (_channels == 0) { - MNN_ERROR("Error: no data found in file %s.", filename.c_str()); - } - - inputShape.resize(3); - auto inputTensorDataFormat = MNN::TensorUtils::getDescribe(_inputTensor)->dimensionFormat; - if (inputTensorDataFormat == MNN::MNN_DATA_FORMAT_NHWC) { - inputShape[0] = 1; - inputShape[1] = _height; - inputShape[2] = _channels; } else { - inputShape[0] = 1; - inputShape[1] = _channels; - inputShape[2] = _height; + mInputs.resize(1); + mInputs[0] = _Input(netInfo->inputs[0].dim, netInfo->inputs[0].order, netInfo->inputs[0].type); + auto inputTensor = (MNN::Tensor*)mInputs[0]->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, _calibrationFiles[0], inputTensor, _inputType); + // auto dest = mInputs[0]->writeMap(); + // Helper::preprocessInput((float*)dest, _process.get(), _preprocessConfig, _imageProcessConfig, _calibrationFiles[0], 4, _inputType); // 4 for C4 dimensionType. +// Helper::preprocessInput(_process.get(), _preprocessConfig, _calibrationFiles[0], inputTensor, _inputType); } - } - - return inputShape; -} - -void Calibration::_resizeIfNeeded(std::string filename, bool force) { - std::vector inputShape = _getInputShape(filename); - - if ((inputShape != _inputTensorDims && _featureQuantizeMethod == "KL") || force) { - _inputTensorDims = inputShape; - _interpreter->resizeTensor(_inputTensor, _inputTensorDims); - _interpreter->resizeSession(_session); - _interpreterOrigin->resizeTensor(_inputTensorOrigin, _inputTensorDims); - _interpreterOrigin->resizeSession(_sessionOrigin); + _initMaps(); } } void Calibration::_initMNNSession(const uint8_t* modelBuffer, const int bufferSize) { - _interpreterOrigin.reset(MNN::Interpreter::createFromBuffer(modelBuffer, bufferSize), MNN::Interpreter::destroy); - MNN::ScheduleConfig config; - _sessionOrigin = _interpreterOrigin->createSession(config); - _inputTensorOrigin = _interpreterOrigin->getSessionInput(_sessionOrigin, NULL); - _fake_quant_weights(); - - flatbuffers::FlatBufferBuilder builder(1024); - auto offset = MNN::Net::Pack(builder, _originalModel); - builder.Finish(offset); - int size = builder.GetSize(); - auto buffer = builder.GetBufferPointer(); - - _interpreter.reset(MNN::Interpreter::createFromBuffer(buffer, size), MNN::Interpreter::destroy); - _session = _interpreter->createSession(config); - _inputTensor = _interpreter->getSessionInput(_session, NULL); - - if (_featureQuantizeMethod == "ADMM") { - DCHECK((_calibrationFileNum * 4 * _height * _width) < (INT_MAX / 4)) << "Use Little Number of Images When Use ADMM"; - for (auto file : _calibrationFiles) { - std::vector sampleShape = _getInputShape(file); - if (_inputTensorDims.empty()) { - _inputTensorDims = sampleShape; - } - if (sampleShape != _inputTensorDims) { - MNN_ERROR("samples must have the same shape when using ADMM method for sequence inputs."); - } - } - _inputTensorDims[0] = _calibrationFileNum; - _interpreter->resizeTensor(_inputTensor, _inputTensorDims); - _interpreter->resizeSession(_session); - _interpreterOrigin->resizeTensor(_inputTensorOrigin, _inputTensorDims); - _interpreterOrigin->resizeSession(_sessionOrigin); - } - - _resizeIfNeeded(_calibrationFiles[0]); } void Calibration::_initMaps() { @@ -358,15 +485,18 @@ void Calibration::_initMaps() { if (iter != _skip_quant_ops.end()) { return false; } - for (auto t : nTensors) { + for (auto t : nTensors) { auto des = TensorUtils::getDescribe(t); if (des->index >= 0) { - _tensorMap[des->index] = t;; + _tensorMap[des->index] = t; } } if (Helper::gNotNeedFeatureOp.find(info->type()) == Helper::gNotNeedFeatureOp.end()) { int i = 0; for (auto t : nTensors) { + if (TensorUtils::getDescribe(t)->index < 0) { + continue; + } if (_featureInfo.find(t) == _featureInfo.end() && MNN::TensorUtils::getDescribe(t)->memoryType != MNN::Tensor::InsideDescribe::MEMORY_VIRTUAL) { _featureInfo[t] = std::shared_ptr( new TensorStatistic(t, _featureQuantizeMethod, opName + " input_tensor_" + flatbuffers::NumToString(i), _featureClampValue)); @@ -386,12 +516,15 @@ void Calibration::_initMaps() { for (auto t : nTensors) { auto des = TensorUtils::getDescribe(t); if (des->index >= 0) { - _tensorMap[des->index] = t;; + _tensorMap[des->index] = t; } } if (Helper::gNotNeedFeatureOp.find(info->type()) == Helper::gNotNeedFeatureOp.end()) { int i = 0; for (auto t : nTensors) { + if (TensorUtils::getDescribe(t)->index < 0) { + continue; + } if (_featureInfo.find(t) == _featureInfo.end()) { _featureInfo[t] = std::shared_ptr(new TensorStatistic(t, _featureQuantizeMethod, opName + " output_tensor_" + flatbuffers::NumToString(i), _featureClampValue)); @@ -401,51 +534,21 @@ void Calibration::_initMaps() { } return true; }; - _interpreter->runSessionWithCallBackInfo(_session, before, after); - - MNN::TensorCallBackWithInfo beforeOrigin = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { - std::string opName = info->name(); - std::vector::iterator iter = std::find(_skip_quant_ops.begin(), _skip_quant_ops.end(), opName); - if (iter != _skip_quant_ops.end()) { - return false; - } - if (Helper::gNotNeedFeatureOp.find(info->type()) == Helper::gNotNeedFeatureOp.end()) { - int i = 0; - for (auto t : nTensors) { - if (_featureInfoOrigin.find(t) == _featureInfoOrigin.end()) { - _featureInfoOrigin[t] = std::shared_ptr( - new TensorStatistic(t, _featureQuantizeMethod, opName + " input_tensor_" + flatbuffers::NumToString(i), _featureClampValue)); - } - i++; - } - } - return false; - }; - MNN::TensorCallBackWithInfo afterOrigin = [this](const std::vector& nTensors, - const MNN::OperatorInfo* info) { - std::string opName = info->name(); - std::vector::iterator iter = std::find(_skip_quant_ops.begin(), _skip_quant_ops.end(), opName); - if (iter != _skip_quant_ops.end()) { - return true; - } - if (Helper::gNotNeedFeatureOp.find(info->type()) == Helper::gNotNeedFeatureOp.end()) { - int i = 0; - for (auto t : nTensors) { - if (_featureInfoOrigin.find(t) == _featureInfoOrigin.end()) { - _featureInfoOrigin[t] = - std::shared_ptr(new TensorStatistic(t, _featureQuantizeMethod, opName + " output_tensor_" + flatbuffers::NumToString(i), _featureClampValue)); - } - i++; - } - } - return true; - }; - _interpreterOrigin->runSessionWithCallBackInfo(_sessionOrigin, beforeOrigin, afterOrigin); + Express::Executor::getGlobalExecutor()->setCallBack(std::move(before), std::move(after)); + // auto netInfo = _module->getInfo(); + // for (int k = 0; k < mInputs.size(); ++k) { + // mInputs[k] = _Convert(mInputs[k], netInfo->inputs[k].order); + // } + auto outputs = _module->onForward(mInputs); + for (auto& output_: outputs) { + output_->readMap(); + } + _featureInfoOrigin = _featureInfo; if (_featureQuantizeMethod == "KL") { // set the tensor-statistic method of input tensor as THRESHOLD_MAX - auto inputTensorStatistic = _featureInfo.find(_inputTensor); + auto inputTensorStatistic = _featureInfo.find(mInputs[0]->getTensor()); if (inputTensorStatistic != _featureInfo.end()) { inputTensorStatistic->second->setThresholdMethod(THRESHOLD_MAX); } @@ -455,21 +558,39 @@ void Calibration::_initMaps() { void Calibration::_computeFeatureMapsRange() { // feed input data according to input images int count = 0; - for (const auto& file : _calibrationFiles) { + + auto netInfo = _module->getInfo(); + for (const auto& file: _calibrationFiles) { + std::vector inputs; for (auto& iter : _featureInfo) { iter.second->setVisited(false); } - for (auto& iter : _featureInfo) { iter.second->resetUpdatedRangeFlags(); } - count++; - _resizeIfNeeded(file); - Helper::preprocessInput(_process.get(), _preprocessConfig, file, _inputTensor, _inputType); + + if (_inputType == Helper::SEQUENCE) { + inputs = getModuleInputs(file, netInfo, mInputNames, mInputShape); + for (int i = 0; i < inputs.size(); ++i) { + auto input = inputs[i]; + auto name = mInputNames[i]; + std::string fileName = file + "/" + name + ".txt"; + auto inputTensor = (MNN::Tensor*)input->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, fileName, inputTensor, _inputType); + } + } else { + auto inputTensor = (MNN::Tensor*)mInputs[0]->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, file, inputTensor, _inputType); + // auto dest = mInputs[0]->writeMap(); + // Helper::preprocessInput((float*)dest, _process.get(), _preprocessConfig, _imageProcessConfig, file, 4, _inputType); // 4 for C4 dimensionType. + } MNN::TensorCallBackWithInfo before = [&](const std::vector& nTensors, - const MNN::OperatorInfo* info) { + const MNN::OperatorInfo* info) { for (auto t : nTensors) { + if (TensorUtils::getDescribe(t)->index < 0) { + continue; + } if (_featureInfo.find(t) != _featureInfo.end()) { if (_featureInfo[t]->visited() == false) { _featureInfo[t]->updateRange(); @@ -481,6 +602,9 @@ void Calibration::_computeFeatureMapsRange() { MNN::TensorCallBackWithInfo after = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { for (auto t : nTensors) { + if (TensorUtils::getDescribe(t)->index < 0) { + continue; + } if (_featureInfo.find(t) != _featureInfo.end()) { if (_featureInfo[t]->visited() == false) { _featureInfo[t]->updateRange(); @@ -489,12 +613,10 @@ void Calibration::_computeFeatureMapsRange() { } return true; }; - - _interpreter->runSessionWithCallBackInfo(_session, before, after); - MNN_PRINT("\rComputeFeatureRange: %.2lf %%", (float)count * 100.0f / (float)_calibrationFileNum); - fflush(stdout); + Express::Executor::getGlobalExecutor()->setCallBack(std::move(before), std::move(after)); + auto outputs = _module->onForward(mInputs); + // outputs[0]->readMap(); } - MNN_PRINT("\n"); } void Calibration::_collectFeatureMapsDistribution() { @@ -502,26 +624,6 @@ void Calibration::_collectFeatureMapsDistribution() { iter.second->resetDistribution(); } // feed input data according to input images - MNN::TensorCallBackWithInfo before = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { - for (auto t : nTensors) { - if (_featureInfo.find(t) != _featureInfo.end()) { - if (_featureInfo[t]->visited() == false) { - _featureInfo[t]->updateDistribution(); - } - } - } - return true; - }; - MNN::TensorCallBackWithInfo after = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { - for (auto t : nTensors) { - if (_featureInfo.find(t) != _featureInfo.end()) { - if (_featureInfo[t]->visited() == false) { - _featureInfo[t]->updateDistribution(); - } - } - } - return true; - }; int count = 0; for (const auto& file : _calibrationFiles) { count++; @@ -533,9 +635,55 @@ void Calibration::_collectFeatureMapsDistribution() { for (auto& iter : _featureInfo) { iter.second->resetUpdatedDistributionFlag(); } - _resizeIfNeeded(file); - Helper::preprocessInput(_process.get(), _preprocessConfig, file, _inputTensor, _inputType); - _interpreter->runSessionWithCallBackInfo(_session, before, after); + auto netInfo = _module->getInfo(); + std::vector inputs; + // Load inputs + if (_inputType == Helper::SEQUENCE) { + inputs = getModuleInputs(file, netInfo, mInputNames, mInputShape); + for (int i = 0; i < inputs.size(); ++i) { + auto input = inputs[i]; + auto name = mInputNames[i]; + std::string fileName = file + "/" + name + ".txt"; + auto inputTensor = (MNN::Tensor*)input->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, fileName, inputTensor, _inputType); + } + } else { + auto inputTensor = (MNN::Tensor*)mInputs[0]->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, file, inputTensor, _inputType); + // auto dest = mInputs[0]->writeMap(); + // Helper::preprocessInput((float*)dest, _process.get(), _preprocessConfig, _imageProcessConfig, file, 4, _inputType); // 4 for C4 dimensionType. + } + + MNN::TensorCallBackWithInfo before = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { + for (auto t : nTensors) { + if (TensorUtils::getDescribe(t)->index < 0) { + continue; + } + if (_featureInfo.find(t) != _featureInfo.end()) { + if (_featureInfo[t]->visited() == false) { + _featureInfo[t]->updateDistribution(); + } + } + } + return true; + }; + MNN::TensorCallBackWithInfo after = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { + for (auto t : nTensors) { + if (TensorUtils::getDescribe(t)->index < 0) { + continue; + } + if (_featureInfo.find(t) != _featureInfo.end()) { + if (_featureInfo[t]->visited() == false) { + _featureInfo[t]->updateDistribution(); + } + } + } + return true; + }; + + Express::Executor::getGlobalExecutor()->setCallBack(std::move(before), std::move(after)); + auto outputs = _module->onForward(mInputs); + // outputs[0]->readMap(); MNN_PRINT("\rCollectFeatureDistribution: %.2lf %%", (float)count * 100.0f / (float)_calibrationFileNum); fflush(stdout); @@ -557,21 +705,35 @@ void Calibration::_computeFeatureScaleKL() { void Calibration::_computeFeatureScaleADMM() { // feed input data according to input images - int count = 0; - std::vector oneImageTensorDims = _inputTensorDims; - oneImageTensorDims[0] = 1; - auto inputTensorDataFormat = MNN::TensorUtils::getDescribe(_inputTensor)->dimensionFormat; + int count = 0; + auto netInfo = _module->getInfo(); + std::vector inputs(mInputNames.size()); + std::vector inputTensors(mInputNames.size()); + for (int i = 0; i < inputs.size(); ++i) { + auto shape = mInputShape[mInputNames[i]]; + shape[0] = _calibrationFileNum; + inputs[i] = _Input(shape, netInfo->inputs[i].order, netInfo->inputs[i].type); + inputTensors[i] = inputs[i]->getTensor(); + } auto dimType = MNN::Tensor::CAFFE_C4; - if (inputTensorDataFormat == MNN::MNN_DATA_FORMAT_NHWC) { + if (netInfo->inputs[0].order == NHWC) { dimType = MNN::Tensor::TENSORFLOW; } - for (const auto& file : _calibrationFiles) { - auto curPtr = _inputTensor->host() + count * _inputTensor->stride(0); - std::shared_ptr tensorWarp( - MNN::Tensor::create(oneImageTensorDims, _inputTensor->getType(), curPtr, dimType), MNN::Tensor::destroy); - Helper::preprocessInput(_process.get(), _preprocessConfig, file, tensorWarp.get(), _inputType); - + if (_inputType == Helper::SEQUENCE) { + for (int j = 0; j < inputs.size(); ++j) { + auto name = mInputNames[j]; + std::string fileName = file + "/" + name + ".txt"; + auto inputPtr = inputTensors[j]->host() + count * inputTensors[j]->stride(0); + std::shared_ptr tensor(MNN::Tensor::create(mInputShape[name], netInfo->inputs[j].type, inputPtr, dimType), MNN::Tensor::destroy); + Helper::preprocessInput(_process.get(), _preprocessConfig, fileName, tensor.get(), _inputType); + } + } else { + auto inputPtr = inputTensors[0]->host() + count * inputTensors[0]->stride(0); + auto name = mInputNames[0]; + std::shared_ptr tensor(MNN::Tensor::create(mInputShape[name], netInfo->inputs[0].type, inputPtr, dimType), MNN::Tensor::destroy); + Helper::preprocessInput(_process.get(), _preprocessConfig, file, tensor.get(), _inputType); + } count++; MNN_PRINT("\rProcessCalibrationFiles: %.2lf %%", (float)count * 100.0f / (float)_calibrationFileNum); fflush(stdout); @@ -612,8 +774,8 @@ void Calibration::_computeFeatureScaleADMM() { } return true; }; - - _interpreter->runSessionWithCallBackInfo(_session, before, after); + Express::Executor::getGlobalExecutor()->setCallBack(std::move(before), std::move(after)); + _module->onForward(inputs); MNN_PRINT("\n"); } @@ -698,6 +860,9 @@ void Calibration::_insertScale() { } auto inputTensor = _tensorMap[op->inputIndexes[0]]; auto outputTensor = _tensorMap[op->outputIndexes[0]]; + if (inputTensor == nullptr || outputTensor == nullptr) { + continue; + } // below is Conv/DepthwiseConv weight quant const float inputScale = _scales[inputTensor].first; const float outputScale = _scales[outputTensor].first; @@ -744,18 +909,10 @@ void Calibration::_insertScale() { } void Calibration::_computeQuantError() { - int count = 0; std::map> overflowRatiosMap; std::map> tensorCosDistanceMap; - - for (const auto& file : _calibrationFiles) { - count++; - _resizeIfNeeded(file, true); - Helper::preprocessInput(_process.get(), _preprocessConfig, file, _inputTensor, _inputType); - - std::map> fakeQuantedFeatures; - - MNN::TensorCallBackWithInfo before = [&](const std::vector& nTensors, + std::map> fakeQuantedFeatures; + MNN::TensorCallBackWithInfo before = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { if (info->type() == "Raster") { return true; @@ -770,64 +927,83 @@ void Calibration::_computeQuantError() { } } return true; - }; - MNN::TensorCallBackWithInfo after = [&](const std::vector& nTensors, + }; + MNN::TensorCallBackWithInfo after = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { - for (auto t : nTensors) { - if (_featureInfo.find(t) != _featureInfo.end()) { - if (_featureInfo[t]->visited() == false) { - auto dequantFeatureAndOverflowRatio = _featureInfo[t]->fakeQuantFeature(); - fakeQuantedFeatures[_featureInfo[t]->name()] = dequantFeatureAndOverflowRatio.first; - overflowRatiosMap[_featureInfo[t]->name()].emplace_back(dequantFeatureAndOverflowRatio.second); - } + for (auto t : nTensors) { + if (_featureInfo.find(t) != _featureInfo.end()) { + if (_featureInfo[t]->visited() == false) { + auto dequantFeatureAndOverflowRatio = _featureInfo[t]->fakeQuantFeature(); + fakeQuantedFeatures[_featureInfo[t]->name()] = dequantFeatureAndOverflowRatio.first; + overflowRatiosMap[_featureInfo[t]->name()].emplace_back(dequantFeatureAndOverflowRatio.second); } } - return true; - }; - - for (auto& iter : _featureInfo) { - iter.second->setVisited(false); } + return true; + }; - _interpreter->runSessionWithCallBackInfo(_session, before, after); - - Helper::preprocessInput(_process.get(), _preprocessConfig, file, _inputTensorOrigin, _inputType); - - MNN::TensorCallBackWithInfo beforeOrigin = [&](const std::vector& nTensors, + MNN::TensorCallBackWithInfo beforeOrigin = [&](const std::vector& nTensors, const MNN::OperatorInfo* info) { - if (info->type() == "Raster") { - return true; - } - for (auto t : nTensors) { - if (_featureInfoOrigin.find(t) != _featureInfoOrigin.end()) { - if (_featureInfoOrigin[t]->visited() == false) { - auto name = _featureInfoOrigin[t]->name(); - float cosDis = _featureInfoOrigin[t]->computeDistance(fakeQuantedFeatures[name]); - tensorCosDistanceMap[name].emplace_back(cosDis); - } + if (info->type() == "Raster") { + return true; + } + for (auto t : nTensors) { + if (_featureInfoOrigin.find(t) != _featureInfoOrigin.end()) { + if (_featureInfoOrigin[t]->visited() == false) { + auto name = _featureInfoOrigin[t]->name(); + float cosDis = _featureInfoOrigin[t]->computeDistance(fakeQuantedFeatures[name]); + tensorCosDistanceMap[name].emplace_back(cosDis); } } - return true; - }; - MNN::TensorCallBackWithInfo afterOrigin = [&](const std::vector& nTensors, - const MNN::OperatorInfo* info) { - for (auto t : nTensors) { - if (_featureInfoOrigin.find(t) != _featureInfoOrigin.end()) { - if (_featureInfoOrigin[t]->visited() == false) { - auto name = _featureInfoOrigin[t]->name(); - float cosDis = _featureInfoOrigin[t]->computeDistance(fakeQuantedFeatures[name]); - tensorCosDistanceMap[name].emplace_back(cosDis); - } + } + return true; + }; + MNN::TensorCallBackWithInfo afterOrigin = [&](const std::vector& nTensors, + const MNN::OperatorInfo* info) { + for (auto t : nTensors) { + if (_featureInfoOrigin.find(t) != _featureInfoOrigin.end()) { + if (_featureInfoOrigin[t]->visited() == false) { + auto name = _featureInfoOrigin[t]->name(); + float cosDis = _featureInfoOrigin[t]->computeDistance(fakeQuantedFeatures[name]); + tensorCosDistanceMap[name].emplace_back(cosDis); } } - return true; - }; + } + return true; + }; + int count = 0; + for (const auto& file : _calibrationFiles) { + count++; + + for (auto& iter : _featureInfo) { + iter.second->setVisited(false); + } for (auto& iter : _featureInfoOrigin) { iter.second->setVisited(false); } - - _interpreterOrigin->runSessionWithCallBackInfo(_sessionOrigin, beforeOrigin, afterOrigin); + std::vector inputs(mInputNames.size()); + auto netInfo = _module->getInfo(); + if (_inputType == Helper::SEQUENCE) { + inputs = getModuleInputs(file, netInfo, mInputNames, mInputShape); + for (int i = 0; i < inputs.size(); ++i) { + auto input = inputs[i]; + auto name = mInputNames[i]; + std::string fileName = file + "/" + name + ".txt"; + auto inputTensor = (MNN::Tensor*)input->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, fileName, inputTensor, _inputType); + } + } else { + inputs.resize(1); + inputs[0] = _Input(netInfo->inputs[0].dim, netInfo->inputs[0].order, netInfo->inputs[0].type); + inputs[0] = _Convert(inputs[0], netInfo->inputs[0].order); + auto inputTensor = (MNN::Tensor*)inputs[0]->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, file, inputTensor, _inputType); + } + Express::Executor::getGlobalExecutor()->setCallBack(std::move(before), std::move(after)); + _module->onForward(inputs); + Express::Executor::getGlobalExecutor()->setCallBack(std::move(beforeOrigin), std::move(afterOrigin)); + _moduleOrigin->onForward(inputs); MNN_PRINT("\rcomputeDistance: %.2lf %%", (float)count * 100.0f / (float)_calibrationFileNum); fflush(stdout); @@ -856,13 +1032,9 @@ void Calibration::_quantizeModelEMA() { } auto inputOutputs = Variable::getInputAndOutput(varMap); - auto inputs = Variable::mapToSequence(inputOutputs.first); - auto outputs = Variable::mapToSequence(inputOutputs.second); - if (inputs.size() != 1) { - MNN_ERROR("Only support input size = 1\n"); - return; - } - auto originInfo = inputs[0]->getInfo(); + auto varInputs = Variable::mapToSequence(inputOutputs.first); + auto varOutputs = Variable::mapToSequence(inputOutputs.second); + auto originInfo = varInputs[0]->getInfo(); auto originFormat = NC4HW4; auto originType = halide_type_of(); std::vector originDims; @@ -871,14 +1043,14 @@ void Calibration::_quantizeModelEMA() { originDims = originInfo->dim; originType = originInfo->type; } - std::shared_ptr model(NN::extract(inputs, outputs, true), Module::destroy); - NN::turnQuantize(model.get(), _quant_bits, NN::PerTensor, NN::MovingAverage, _winogradOpt); + _module.reset(NN::extract(varInputs, varOutputs, true), Module::destroy); + NN::turnQuantize(_module.get(), _quant_bits, NN::PerTensor, NN::MovingAverage, _winogradOpt); auto exe = Executor::getGlobalExecutor(); BackendConfig config; - exe->setGlobalExecutorConfig(MNN_FORWARD_CPU, config, 2); + exe->setGlobalExecutorConfig(MNN_FORWARD_CPU, config, 1); - std::shared_ptr solver(new SGD(model)); + std::shared_ptr solver(new SGD(_module)); solver->setLearningRate(1e-5); solver->setMomentum(0.9f); solver->setWeightDecay(0.00004f); @@ -889,95 +1061,102 @@ void Calibration::_quantizeModelEMA() { MNN_ERROR("_calibrationFileNum %d < batch size %d, set batch size as %d\n", _calibrationFileNum, _batch, _calibrationFileNum); _batch = _calibrationFileNum; } - DataLoader* trainDataLoader = nullptr; - std::shared_ptr tempInputTensor = nullptr; - if (_inputType == Helper::InputType::IMAGE) { - auto converImagesToFormat = _imageProcessConfig.destFormat; - int resizeHeight = _preprocessConfig.targetHeight; - int resizeWidth = _preprocessConfig.targetWidth; - std::vector means, scales; - for (int i = 0; i < 4; i++) { - means.emplace_back(_imageProcessConfig.mean[i]); - scales.emplace_back(_imageProcessConfig.normal[i]); - } - std::vector cropFraction = {_preprocessConfig.centerCropHeight, _preprocessConfig.centerCropWidth}; // center crop fraction for height and width - bool centerOrRandomCrop = false; // true for random crop - std::shared_ptr datasetConfig(ImageDataset::ImageConfig::create(converImagesToFormat, resizeHeight, resizeWidth, scales, means, cropFraction, centerOrRandomCrop)); - auto trainDataset = ImageNoLabelDataset::create(_calibrationFilePath, datasetConfig.get()); - - const int trainBatchSize = _batch; - const int trainNumWorkers = 0; - trainDataLoader = trainDataset.createLoader(trainBatchSize, true, false, trainNumWorkers); - trainDataLoader->reset(); - } else { - flatbuffers::FlatBufferBuilder builder(1024); - auto offset = MNN::Net::Pack(builder, _originalModel); - builder.Finish(offset); - int size = builder.GetSize(); - auto buffer = builder.GetBufferPointer(); - _interpreter.reset(MNN::Interpreter::createFromBuffer(buffer, size), MNN::Interpreter::destroy); - MNN::ScheduleConfig config; - _session = _interpreter->createSession(config); - _inputTensor = _interpreter->getSessionInput(_session, NULL); - - _getInputShape(_calibrationFiles[0]); - std::vector tempData(_batch * _channels * _height, 0.0f); - tempInputTensor.reset(MNN::Tensor::create({_batch, _channels, _height}, halide_type_of(), tempData.data(), MNN::Tensor::CAFFE), MNN::Tensor::destroy); - } - const int trainIterations = _calibrationFileNum / _batch; - model->clearCache(); + const int trainIterations = _calibrationFileNum / _batch; + _module->clearCache(); exe->gc(Executor::FULL); - model->setIsTraining(true); - for (int i = 0; i < trainIterations; i++) { - VARP input; - if (_inputType == Helper::InputType::IMAGE) { - auto trainData = trainDataLoader->next(); - auto example = trainData[0]; - input = example.first[0]; + _module->setIsTraining(true); + for (int it = 0; it < trainIterations; it++) { + std::vector inputs(varInputs.size()); // inputs[i].dim=[batch, c, h, w] + int indicesStart = it * _batch; + int indicesEnd = indicesStart + _batch; + // Init batch size inputs + if (_inputType == Helper::IMAGE) { + inputs[0] = _Input({_batch, originDims[1], originDims[2], originDims[3]}, originFormat, originType); } else { - for (auto& file : _calibrationFiles) { - for (int j = 0; j < _batch; j++) { - auto curPtr = tempInputTensor->host() + j * tempInputTensor->stride(0); - std::shared_ptr tensorWarp(MNN::Tensor::create({1, _channels, _height}, _inputTensor->getType(), curPtr, MNN::Tensor::CAFFE), MNN::Tensor::destroy); - Helper::preprocessInput(_process.get(), _preprocessConfig, file, tensorWarp.get(), _inputType); + for (auto& input: inputs) { + input = _Input({_batch, originDims[1], originDims[2], originDims[3]}, originFormat, originType); + } + } + // Compose batch input + for (int k = indicesStart; k < indicesEnd; ++k) { + const auto file = _calibrationFiles[k]; + if (_inputType == Helper::SEQUENCE) { + std::map> dyInputShape = mInputShape; + std::string jsonFile = file + "/" + "input.json"; + std::ifstream f(jsonFile.c_str()); + if (f.is_open()) { + rapidjson::Document document; + std::ostringstream json_os; + json_os << f.rdbuf(); + document.Parse(json_os.str().c_str()); + if (document.HasParseError()) { + MNN_ERROR("Invalid json: %s\n", jsonFile.c_str()); + } + auto cfgObj = document.GetObject(); + if (cfgObj.HasMember("inputs")) { + auto inputsInfo = document["inputs"].GetArray(); + for (auto iter = inputsInfo.begin(); iter !=inputsInfo.end(); iter++) { + auto obj = iter->GetObject(); + std::string name = obj["name"].GetString(); + if (obj.HasMember("shape")) { + auto dims = obj["shape"].GetArray(); + std::vector shapes; + for (auto iter = dims.begin(); iter != dims.end(); iter++) { + shapes.emplace_back(iter->GetInt()); + } + dyInputShape[name] = shapes; + dyInputShape[name][0] = _batch; + } + } + } } - input = _Input({_batch, _channels, _height}, MNN::Express::Dimensionformat::NCHW, halide_type_of()); - auto inputPtr = input->writeMap(); - auto tempInputPtr = tempInputTensor->host(); - for (int j = 0; j < _batch * _channels * _height; j++) { - inputPtr[j] = tempInputPtr[j]; + + for (int i = 0; i < inputs.size(); ++i) { + auto name = varInputs[i]->name(); + auto input = _Input(dyInputShape[name], varInputs[i]->getInfo()->order, varInputs[i]->getInfo()->type); + std::string fileName = file + "/" + name + ".txt"; + + auto inputTensor = (MNN::Tensor*)input->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, fileName, inputTensor, _inputType); + ::memcpy(input->writeMap(), inputTensor->host(), inputTensor->elementSize() * sizeof(float)); + inputs[i] = input; } + } else { + auto singleInput = _Input(originDims, originFormat, originType); + auto inputTensor = (MNN::Tensor*)singleInput->getTensor(); + Helper::preprocessInput(_process.get(), _preprocessConfig, file, inputTensor, _inputType); + ::memcpy(inputs[0]->writeMap() + k * inputTensor->elementSize(), inputTensor->host(), inputTensor->elementSize() * sizeof(float)); + } } - auto predicts = model->onForward({_Convert(input, originFormat)}); - for (auto& output : predicts) { + auto predicts = _module->onForward(inputs); + for (auto &output: predicts) { auto ptr = output->readMap(); } - MNN_PRINT("\rquantize with EMA: %.2lf %%", (i + 1) * 100.0f / trainIterations); + MNN_PRINT("\rquantize with EMA: %.2lf %%", (it + 1) * 100.0f / trainIterations); fflush(stdout); solver->step(_Scalar(0.0f)); } MNN_PRINT("\n"); - model->setIsTraining(false); + _module->setIsTraining(false); exe->gc(Executor::PART); - VARP forwardInput = nullptr; - if (originInfo != nullptr && originDims.size() > 0) { - forwardInput = _Input(originDims, originFormat, originType); - } else { - if (_inputType == Helper::InputType::IMAGE) { - forwardInput = _Input({1, _channels, _preprocessConfig.targetHeight, _preprocessConfig.targetWidth}, NC4HW4); - } else { - forwardInput = _Input({1, _channels, _height}, NC4HW4); - } + std::vector inputsForward; + inputsForward.resize(varInputs.size()); + for (int i = 0; i < inputsForward.size(); ++i) { + auto name = varInputs[i]->name(); + auto input = _Input(mInputShape[name], varInputs[i]->getInfo()->order, varInputs[i]->getInfo()->type); + input->setName(name); + inputsForward[i] = input; } - forwardInput->setName(inputs[0]->name()); - auto predicts = model->onForward({forwardInput}); + + auto predicts = _module->onForward(inputsForward); + Transformer::turnModelToInfer()->onExecute(predicts); for (int i = 0; i < predicts.size(); i++) { - predicts[i]->setName(outputs[i]->name()); + predicts[i]->setName(varOutputs[i]->name()); } Variable::save(predicts, _destModelFile.c_str()); ConvertToFullQuant::convert(_destModelFile); @@ -1213,11 +1392,10 @@ void Calibration::ComputeUnaryBuffer(MNN::NetT* net) { if (type == UnaryOpOperation_ABS || type == UnaryOpOperation_NEG || type == UnaryOpOperation_SIGN) { continue; } - op->main.AsUnaryOp()->tableInt8.resize(255); - auto unaryParam = op->main.AsUnaryOp()->tableInt8.data(); auto outputId = op->outputIndexes[0]; if (describes.find(outputId) == describes.end()) { + MNN_PRINT("Can't find input extraTensorDescribe for %s\n", op->name.c_str()); continue; } auto unaryDes = describes.find(outputId)->second; @@ -1225,8 +1403,11 @@ void Calibration::ComputeUnaryBuffer(MNN::NetT* net) { float outZero = unaryDes->quantInfo->zero; auto inputId = op->inputIndexes[0]; if (describes.find(inputId) == describes.end()) { - MNN_ERROR("Can't find extraTensorDescribe for %s\n", op->name.c_str()); + MNN_PRINT("Can't find input extraTensorDescribe for %s\n", op->name.c_str()); + continue; } + op->main.AsUnaryOp()->tableInt8.resize(255); + auto unaryParam = op->main.AsUnaryOp()->tableInt8.data(); unaryDes = describes.find(inputId)->second; float inpScale = unaryDes->quantInfo->scale; float inpZero = unaryDes->quantInfo->zero; diff --git a/tools/quantization/calibration.hpp b/tools/quantization/calibration.hpp index 0c76316c7..6546ba57a 100644 --- a/tools/quantization/calibration.hpp +++ b/tools/quantization/calibration.hpp @@ -14,6 +14,7 @@ #include #include #include "TensorStatistic.hpp" +#include #include "MNN_generated.h" #include "Helper.hpp" #include "logkit.h" @@ -56,6 +57,13 @@ class Calibration { std::string _destModelFile; MNN::CV::ImageProcess::Config _imageProcessConfig; std::vector _calibrationFiles; + std::vector mCalibrationDatasetDir; + std::vector mInputNames; + std::vector mOutputNames; + std::map mInputInfo; + std::map> mInputShape; + std::vector mInputs; + std::shared_ptr mBackend; // Tensor and Info std::map> _featureInfo; @@ -65,15 +73,12 @@ class Calibration { // The scale results std::map> _scales; - std::shared_ptr _interpreter; // keep mnn forward information - MNN::Session* _session; - MNN::Tensor* _inputTensor; + std::vector mInputTensors; std::vector _inputTensorDims; - std::shared_ptr _interpreterOrigin; - MNN::Session* _sessionOrigin; - MNN::Tensor* _inputTensorOrigin; + std::shared_ptr _module; + std::shared_ptr _moduleOrigin; std::string _featureQuantizeMethod = "KL"; std::string _weightQuantizeMethod = "MAX_ABS"; diff --git a/transformers/diffusion/README.md b/transformers/diffusion/README.md new file mode 100644 index 000000000..42d247ca8 --- /dev/null +++ b/transformers/diffusion/README.md @@ -0,0 +1,45 @@ +# Diffusion使用方法 + +## 模型支持与下载 + +[Download-runwayml/stable-diffusion-v1-5]: +https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main +[Download-IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1]: +https://huggingface.co/IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1/tree/main + +## 模型转换 +### 将Huggingface的Stable Diffusion模型 转为onnx模型 +python export/onnx_export.py \ + --model_path hf_sd_load_path \ + --output_path onnx_save_path + +### 将onnx模型转为mnn模型 +新建diffusion mnn模型文件夹,将转好的mnn文件放在该文件夹下。 +./MNNConvert -f ONNX --modelFile onnx_save_path/text_encoder/model.onnx --MNNModel mnn_save_path/text_encoder.mnn --weightQuantBits 8 --bizCode biz +./MNNConvert -f ONNX --modelFile onnx_save_path/unet/model.onnx --MNNModel mnn_save_path/unet.mnn --transformerFuse --weightQuantBits 8 --bizCode biz +./MNNConvert -f ONNX --modelFile onnx_save_path/vae_decoder/model.onnx --keepInputFormat --MNNModel mnn_save_path/vae_decoder.mnn --weightQuantBits 8 --bizCode biz + +## 编译Diffusion Demo +### Linux/MAC/Windows上 +cmake .. -DMNN_BUILD_DIFFUSION=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_OPENCL=ON -DMNN_SEP_BUILD=OFF -DMNN_SUPPORT_TRANSFORMER_FUSE=ON + +### Android上 +cd project/android/build +../build_64.sh -DMNN_BUILD_DIFFUSION=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_OPENCL=ON -DMNN_SEP_BUILD=OFF -DMNN_SUPPORT_TRANSFORMER_FUSE=ON + +## 运行Diffusion Demo +./diffusion_demo +其中,resource_path 就是mnn模型文件的路径,除了mnn文件,还需要 +(1)将MNN目录transformers/diffusion/scheduler/alphas.txt文件拷贝到该文件夹下。 +(2)针对stable-diffusion-v1-5模型需要将huggingfacetokenizer目录下merges.txt和vocab.json拷贝到该文件夹中。针对Taiyi-Stable-Diffusion模型需要将huggingfacetokenizer目录下vocab.txt拷贝到该文件夹中。 + +model_type是目前支持的两种diffusion模型的类别。如果是stable-diffusion-v1-5模型设为0,如果是Taiyi-Stable-Diffusion模型设为1。 + +output_image_name是生成图片的名字,默认图片位置在当前运行目录下。 + +input_text是文生图的prompt,如果是stable-diffusion-v1-5模型建议英文prompt,如果是Taiyi-Stable-Diffusion建议中文prompt。 + +运行指令例如: +./diffusion_demo mnn_save_path 0 demo.jpg "a cute cat" +./diffusion_demo mnn_save_path 1 demo.jpg "一只可爱的猫" + diff --git a/transformers/diffusion/export/onnx_export.py b/transformers/diffusion/export/onnx_export.py new file mode 100644 index 000000000..21f05e83b --- /dev/null +++ b/transformers/diffusion/export/onnx_export.py @@ -0,0 +1,212 @@ +# Copyright 2024 The HuggingFace Team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import os +import shutil +from pathlib import Path + +import torch +from torch.onnx import export + +import onnx +from diffusers import OnnxStableDiffusionPipeline, StableDiffusionPipeline +from packaging import version + + +is_torch_less_than_1_11 = version.parse(version.parse(torch.__version__).base_version) < version.parse("1.11") + + +def onnx_export( + model, + model_args: tuple, + output_path: Path, + ordered_input_names, + output_names, + dynamic_axes, + opset, + use_external_data_format=False, +): + output_path.parent.mkdir(parents=True, exist_ok=True) + # PyTorch deprecated the `enable_onnx_checker` and `use_external_data_format` arguments in v1.11, + # so we check the torch version for backwards compatibility + if is_torch_less_than_1_11: + export( + model, + model_args, + f=output_path.as_posix(), + input_names=ordered_input_names, + output_names=output_names, + dynamic_axes=dynamic_axes, + do_constant_folding=True, + use_external_data_format=use_external_data_format, + enable_onnx_checker=True, + opset_version=opset, + ) + else: + export( + model, + model_args, + f=output_path.as_posix(), + input_names=ordered_input_names, + output_names=output_names, + dynamic_axes=dynamic_axes, + do_constant_folding=True, + opset_version=opset, + ) + + +@torch.no_grad() +def convert_models(model_path: str, output_path: str, opset: int, fp16: bool = False): + dtype = torch.float16 if fp16 else torch.float32 + if fp16 and torch.cuda.is_available(): + device = "cuda" + elif fp16 and not torch.cuda.is_available(): + raise ValueError("`float16` model export is only supported on GPUs with CUDA") + else: + device = "cpu" + device = "cpu" + pipeline = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=dtype).to(device) + output_path = Path(output_path) + + # TEXT ENCODER + num_tokens = pipeline.text_encoder.config.max_position_embeddings + text_hidden_size = pipeline.text_encoder.config.hidden_size + text_input = pipeline.tokenizer( + "A sample prompt", + padding="max_length", + max_length=pipeline.tokenizer.model_max_length, + truncation=True, + return_tensors="pt", + ) + onnx_export( + pipeline.text_encoder, + # casting to torch.int32 until the CLIP fix is released: https://github.com/huggingface/transformers/pull/18515/files + model_args=(text_input.input_ids.to(device=device, dtype=torch.int32)), + output_path=output_path / "text_encoder" / "model.onnx", + ordered_input_names=["input_ids"], + output_names=["last_hidden_state", "pooler_output"], + dynamic_axes={ + "input_ids": {0: "batch", 1: "sequence"}, + }, + opset=opset, + ) + del pipeline.text_encoder + + # UNET + unet_in_channels = pipeline.unet.config.in_channels + unet_sample_size = pipeline.unet.config.sample_size + unet_path = output_path / "unet" / "model.onnx" + onnx_export( + pipeline.unet, + model_args=( + torch.randn(2, unet_in_channels, unet_sample_size, unet_sample_size).to(device=device, dtype=dtype), + torch.randn(2).to(device=device, dtype=torch.int32), + torch.randn(2, num_tokens, text_hidden_size).to(device=device, dtype=dtype), + # False, + ), + output_path=unet_path, + ordered_input_names=["sample", "timestep", "encoder_hidden_states", "return_dict"], + output_names=["out_sample"], # has to be different from "sample" for correct tracing + dynamic_axes={ + "sample": {0: "batch", 1: "channels", 2: "height", 3: "width"}, + "timestep": {0: "batch"}, + "encoder_hidden_states": {0: "batch", 1: "sequence"}, + }, + opset=opset, + use_external_data_format=True, # UNet is > 2GB, so the weights need to be split + ) + unet_model_path = str(unet_path.absolute().as_posix()) + unet_dir = os.path.dirname(unet_model_path) + unet = onnx.load(unet_model_path) + # clean up existing tensor files + shutil.rmtree(unet_dir) + os.mkdir(unet_dir) + # collate external tensor files into one + onnx.save_model( + unet, + unet_model_path, + save_as_external_data=True, + all_tensors_to_one_file=True, + location="weights.pb", + convert_attribute=False, + ) + del pipeline.unet + + # VAE ENCODER + vae_encoder = pipeline.vae + vae_in_channels = vae_encoder.config.in_channels + vae_sample_size = vae_encoder.config.sample_size + # need to get the raw tensor output (sample) from the encoder + vae_encoder.forward = lambda sample, return_dict: vae_encoder.encode(sample, return_dict)[0].sample() + onnx_export( + vae_encoder, + model_args=( + torch.randn(1, vae_in_channels, vae_sample_size, vae_sample_size).to(device=device, dtype=dtype), + False, + ), + output_path=output_path / "vae_encoder" / "model.onnx", + ordered_input_names=["sample", "return_dict"], + output_names=["latent_sample"], + dynamic_axes={ + "sample": {0: "batch", 1: "channels", 2: "height", 3: "width"}, + }, + opset=opset, + ) + + # VAE DECODER + vae_decoder = pipeline.vae + vae_latent_channels = vae_decoder.config.latent_channels + vae_out_channels = vae_decoder.config.out_channels + # forward only through the decoder part + vae_decoder.forward = vae_encoder.decode + onnx_export( + vae_decoder, + model_args=( + torch.randn(1, vae_latent_channels, unet_sample_size, unet_sample_size).to(device=device, dtype=dtype), + False, + ), + output_path=output_path / "vae_decoder" / "model.onnx", + ordered_input_names=["latent_sample", "return_dict"], + output_names=["sample"], + dynamic_axes={ + "latent_sample": {0: "batch", 1: "channels", 2: "height", 3: "width"}, + }, + opset=opset, + ) + del pipeline.vae + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--model_path", + type=str, + required=True, + help="Path to the `diffusers` checkpoint to convert (either a local directory or on the Hub).", + ) + + parser.add_argument("--output_path", type=str, required=True, help="Path to the output model.") + + parser.add_argument( + "--opset", + default=14, + type=int, + help="The version of the ONNX operator set to use.", + ) + parser.add_argument("--fp16", action="store_true", default=False, help="Export the models in `float16` mode") + + args = parser.parse_args() + + convert_models(args.model_path, args.output_path, args.opset, args.fp16) diff --git a/transformers/diffusion/main.cpp b/transformers/diffusion/main.cpp index 23f3f33c2..4cbb03d1e 100644 --- a/transformers/diffusion/main.cpp +++ b/transformers/diffusion/main.cpp @@ -3,15 +3,16 @@ int main(int argc, const char* argv[]) { if (argc < 3) { - printf("Usage: ./diffusion_demo "); + printf("Usage: ./diffusion_demo \n"); return 0; } auto resource_path = argv[1]; - auto img_name = argv[2]; + auto model_type = (diffusion::DiffusionModelType)atoi(argv[2]); + auto img_name = argv[3]; std::string input_text; - for (int i = 3; i < argc; ++i) { + for (int i = 4; i < argc; ++i) { input_text += argv[i]; if (i < argc - 1) { input_text += " "; @@ -19,10 +20,18 @@ int main(int argc, const char* argv[]) { } printf("model resource path: %s\n", resource_path); + if(model_type == diffusion::STABLE_DIFFUSION_1_5) { + printf("model resourc is stable diffusion 1.5\n"); + } else if (model_type == diffusion::STABLE_DIFFUSION_TAIYI_CHINESE) { + printf("model resourc is stable diffusion taiyi chinese version\n"); + } else { + printf("model type: %d not supported, please check\n", (int)model_type); + } printf("output img_name: %s\n", img_name); printf("input texts: %s\n", input_text.c_str()); + - diffusion::Pipeline pipeline(resource_path); + diffusion::Pipeline pipeline(resource_path, model_type); pipeline.run(input_text, img_name); return 0; } diff --git a/transformers/diffusion/pipeline.cpp b/transformers/diffusion/pipeline.cpp index 57a16443e..32d794684 100644 --- a/transformers/diffusion/pipeline.cpp +++ b/transformers/diffusion/pipeline.cpp @@ -18,9 +18,6 @@ #include #endif -//#define TEXT_MAX_LEN 512 // Taiyi_SD -#define TEXT_MAX_LEN 77 // SD_1.5 - //#define MNN_DUMP_DATA using namespace CV; @@ -55,7 +52,12 @@ void display_progress(int cur, int total){ fflush(stdout); } -Pipeline::Pipeline(std::string modelPath) : mModelPath(modelPath) { +Pipeline::Pipeline(std::string modelPath, DiffusionModelType modelType) : mModelPath(modelPath), mModelType(modelType) { + if(modelType == STABLE_DIFFUSION_1_5) { + mMaxTextLen = 77; + } else if(modelType == diffusion::STABLE_DIFFUSION_TAIYI_CHINESE) { + mMaxTextLen = 512; + } std::ifstream alphaFile(modelPath + "/alphas.txt"); int index = 0; float alpha; @@ -70,25 +72,28 @@ Pipeline::Pipeline(std::string modelPath) : mModelPath(modelPath) { 161, 141, 121, 101, 81, 61, 41, 21, 1 }; mTimeSteps = { // 20 steps - 951, 901, 901, 851, 801, 751, 701, 651, 601, 551, 501, 451, - 401, 351, 301, 251, 201, 151, 101, 51, 1 + 951, 901, 901, 851, 801, 751, 701, 651, 601, 551, 501, 451, + 401, 351, 301, 251, 201, 151, 101, 51, 1 }; + mTimeSteps = { // 5 steps + 801, 601, 601, + 401, 201, 1 + }; #endif mTimeSteps = { - 801, 601, 601, - 401, 201, 1 + 951, 901, 901, 851, 801, 751, 701, 651, 601, 551, 501, 451, + 401, 351, 301, 251, 201, 151, 101, 51, 1 }; } bool Pipeline::load_modules(std::string modelPath) { AUTOTIME; - ScheduleConfig config; BackendConfig backendConfig; // config.type = MNN_FORWARD_CPU; config.type = MNN_FORWARD_OPENCL; - config.numThread = 65; - backendConfig.precision = BackendConfig::Precision_Normal; + config.mode = MNN_GPU_MEMORY_BUFFER | MNN_GPU_TUNING_FAST; + backendConfig.precision = BackendConfig::Precision_Low; backendConfig.memory = BackendConfig::Memory_Low; config.backendConfig = &backendConfig; @@ -98,30 +103,52 @@ bool Pipeline::load_modules(std::string modelPath) { // module_config.rearrange = true; runtime_manager_.reset(Executor::RuntimeManager::createRuntimeManager(config)); - // if (config.type == MNN_FORWARD_OPENCL) { - // const char* cacheFileName = ".tempcache"; - // runtime_manager_->setCache(cacheFileName); - // } + if (config.type == MNN_FORWARD_OPENCL) { + const char* cacheFileName = ".tempcache"; + runtime_manager_->setCache(cacheFileName); + } + + mLatentVar = _Input({1, 4, 64, 64}, NCHW, halide_type_of()); + mPromptVar = _Input({2, mMaxTextLen}, NCHW, halide_type_of()); + mTimestepVar = _Input({1}, NCHW, halide_type_of()); + mSampleVar = _Concat({mLatentVar, mLatentVar}, 0); + printf("Model loading and initilizing...\n"); + printf("First time initilizing may cost a few seconds to create cachefile, please wait ...\n"); + + VARP text_embeddings; mModules.resize(3); // load text_encoder model { std::string model_path = modelPath + "/text_encoder.mnn"; mModules[0].reset(Module::load( {"input_ids"}, {"last_hidden_state", "pooler_output"}, model_path.c_str(), runtime_manager_, &module_config)); + + auto outputs = mModules[0]->onForward({mPromptVar}); + text_embeddings = _Convert(outputs[0], NCHW); + display_progress(1, 3); } // load unet model { std::string model_path = modelPath + "/unet.mnn"; mModules[1].reset(Module::load( {"sample", "timestep", "encoder_hidden_states"}, {"out_sample"}, model_path.c_str(), runtime_manager_, &module_config)); + + auto outputs = mModules[1]->onForward({mSampleVar, mTimestepVar, text_embeddings}); + + auto output = _Convert(outputs[0], NCHW); + display_progress(2, 3); } // load vae_decoder model { std::string model_path = modelPath + "/vae_decoder.mnn"; mModules[2].reset(Module::load( {"latent_sample"}, {"sample"}, model_path.c_str(), runtime_manager_, &module_config)); + + auto outputs = mModules[2]->onForward({mLatentVar}); + auto output = _Convert(outputs[0], NCHW); + display_progress(3, 3); } auto exe = ExecutorScope::Current(); @@ -132,16 +159,18 @@ bool Pipeline::load_modules(std::string modelPath) { } VARP Pipeline::text_encoder(const std::vector& ids) { - auto inputs_ids_ = _Const(ids.data(), {2, TEXT_MAX_LEN}, NCHW, halide_type_of()); + AUTOTIME; - auto outputs = mModules[0]->onForward({inputs_ids_}); + memcpy((void *)mPromptVar->writeMap(), ids.data(), 2*mMaxTextLen*sizeof(int)); + + auto outputs = mModules[0]->onForward({mPromptVar}); auto output = _Convert(outputs[0], NCHW); output.fix(VARP::CONSTANT); #ifdef MNN_DUMP_DATA auto xx = output->readMap(); for(int i=0; i<10; i+=2) { - printf("%f %f ", xx[i], xx[i+TEXT_MAX_LEN*768]); + printf("%f %f ", xx[i], xx[i+mMaxTextLen*768]); } printf("\n\n"); #endif @@ -206,16 +235,13 @@ VARP Pipeline::unet(VARP text_embeddings) { } #endif - // VARP latentvar = _Const(initVal.data(), {1, 4, 64, 64}, NCHW); - VARP latentvar = _Input({1, 4, 64, 64}, NCHW, halide_type_of()); - memcpy((void *)latentvar->writeMap(), initVal.data(), 16384*sizeof(float)); + memcpy((void *)mLatentVar->writeMap(), initVal.data(), 16384*sizeof(float)); VARP scalevar = _Input({1}, NCHW, halide_type_of()); auto scaleptr = scalevar->writeMap(); scaleptr[0] = 7.5; - VARP timestepvar = _Input({1}, NCHW, halide_type_of()); auto floatVar = _Input({1}, NCHW, halide_type_of()); auto ptr = floatVar->writeMap(); @@ -223,19 +249,15 @@ VARP Pipeline::unet(VARP text_embeddings) { AUTOTIME; display_progress(i, mTimeSteps.size()); - auto t0 = getTime(); - int timestep = mTimeSteps[i]; ptr[0] = timestep; auto temp = _Cast(floatVar, halide_type_of()); - timestepvar->input(temp); - - VARP samplevar = _Concat({latentvar, latentvar}, 0); - auto outputs = mModules[1]->onForward({samplevar, timestepvar, text_embeddings}); + mTimestepVar->input(temp); + mSampleVar = _Concat({mLatentVar, mLatentVar}, 0); + auto outputs = mModules[1]->onForward({mSampleVar, mTimestepVar, text_embeddings}); auto output = _Convert(outputs[0], NCHW); - auto t1 = getTime(); auto noise_pred = output; @@ -244,42 +266,41 @@ VARP Pipeline::unet(VARP text_embeddings) { auto noise_pred_text = splitvar[1]; noise_pred = scalevar * (noise_pred_text - noise_pred_uncond) + noise_pred_uncond; - auto t2 = getTime(); - latentvar = step_plms(latentvar, noise_pred, i); - auto t3 = getTime(); - MNN_PRINT("Times: %f %f %f ms\n", (t1-t0)/ 1000.0f, (t2-t1)/ 1000.0f, (t3-t2)/ 1000.0f); - // latentvar.fix(VARP::CONSTANT); + mLatentVar = step_plms(mLatentVar, noise_pred, i); + + // mLatentVar.fix(VARP::CONSTANT); #ifdef MNN_DUMP_DATA auto xx = output->readMap(); - auto yy = samplevar->readMap(); + auto yy = mSampleVar->readMap(); auto zz = text_embeddings->readMap(); for(int i=0; i<6; i+=2) { printf("%f %f %f ", xx[i], yy[i], zz[i]); } for(int i=0; i<6; i+=2) { - printf("%f %f %f ", xx[16384+i], yy[16384+i], zz[TEXT_MAX_LEN*768+i]); + printf("%f %f %f ", xx[16384+i], yy[16384+i], zz[mMaxTextLen*768+i]); } printf("\n\n"); #endif } - latentvar.fix(VARP::CONSTANT); + mLatentVar.fix(VARP::CONSTANT); #ifdef MNN_DUMP_DATA - auto xx = latentvar->readMap(); + auto xx = mLatentVar->readMap(); for(int i=0; i<10; i+=2) { printf("%f ", xx[i]); } printf("\n\n"); #endif - return latentvar; + return mLatentVar; } VARP Pipeline::vae_decoder(VARP latent) { mModules[1].reset(); latent = latent * _Const(1 / 0.18215); + AUTOTIME; auto outputs = mModules[2]->onForward({latent}); auto output = _Convert(outputs[0], NCHW); @@ -302,23 +323,25 @@ VARP Pipeline::vae_decoder(VARP latent) { bool Pipeline::run(const std::string& sentence, const std::string& img_name) { std::unique_ptr tok; -// tok.reset(new diffusion::BertTokenizer); - tok.reset(new diffusion::CLIPTokenizer); + if(mModelType == STABLE_DIFFUSION_1_5) { + tok.reset(new diffusion::CLIPTokenizer); + } else if(mModelType == STABLE_DIFFUSION_TAIYI_CHINESE) { + tok.reset(new diffusion::BertTokenizer); + } tok->load(mModelPath); load_modules(mModelPath); - + AUTOTIME; - auto ids = tok->encode(sentence, TEXT_MAX_LEN); + auto ids = tok->encode(sentence, mMaxTextLen); auto text_embeddings = text_encoder(ids); - + auto latent = unet(text_embeddings); + auto image = vae_decoder(latent); bool res = imwrite(img_name, image); if (res) { printf("SUCCESS! write to %s\n", img_name.c_str()); } - // runtime_manager_->updateCache(); - return res; + return true; } - } diff --git a/transformers/diffusion/pipeline.hpp b/transformers/diffusion/pipeline.hpp index b00cec0fb..2d8cc2811 100644 --- a/transformers/diffusion/pipeline.hpp +++ b/transformers/diffusion/pipeline.hpp @@ -11,9 +11,15 @@ using namespace MNN::Express; namespace diffusion { +typedef enum { + STABLE_DIFFUSION_1_5 = 0, + STABLE_DIFFUSION_TAIYI_CHINESE = 1, + DIFFUSION_MODEL_USER +} DiffusionModelType; + class Pipeline { public: - Pipeline(std::string modelPath); + Pipeline(std::string modelPath, DiffusionModelType modelType); ~Pipeline() = default; bool run(const std::string& sentence, const std::string& img_name); private: @@ -27,11 +33,14 @@ class Pipeline { std::vector> mModules; std::string mModelPath; + DiffusionModelType mModelType; + int mMaxTextLen = 77; // step_plms std::vector mTimeSteps; std::vector mAlphas; std::vector mEts; VARP mSample; + VARP mLatentVar, mPromptVar, mTimestepVar, mSampleVar; }; } diff --git a/transformers/diffusion/scheduler/alphas.txt b/transformers/diffusion/scheduler/alphas.txt new file mode 100755 index 000000000..9e1c30b9d --- /dev/null +++ b/transformers/diffusion/scheduler/alphas.txt @@ -0,0 +1,1000 @@ +0.9991 +0.9983 +0.9974 +0.9966 +0.9957 +0.9948 +0.9940 +0.9931 +0.9922 +0.9913 +0.9904 +0.9895 +0.9886 +0.9877 +0.9868 +0.9859 +0.9850 +0.9841 +0.9832 +0.9822 +0.9813 +0.9804 +0.9794 +0.9785 +0.9776 +0.9766 +0.9757 +0.9747 +0.9737 +0.9728 +0.9718 +0.9708 +0.9698 +0.9689 +0.9679 +0.9669 +0.9659 +0.9649 +0.9639 +0.9629 +0.9619 +0.9609 +0.9599 +0.9588 +0.9578 +0.9568 +0.9557 +0.9547 +0.9537 +0.9526 +0.9516 +0.9505 +0.9495 +0.9484 +0.9473 +0.9463 +0.9452 +0.9441 +0.9430 +0.9420 +0.9409 +0.9398 +0.9387 +0.9376 +0.9365 +0.9354 +0.9343 +0.9332 +0.9320 +0.9309 +0.9298 +0.9287 +0.9275 +0.9264 +0.9252 +0.9241 +0.9229 +0.9218 +0.9206 +0.9195 +0.9183 +0.9171 +0.9160 +0.9148 +0.9136 +0.9124 +0.9112 +0.9100 +0.9089 +0.9077 +0.9065 +0.9052 +0.9040 +0.9028 +0.9016 +0.9004 +0.8992 +0.8979 +0.8967 +0.8955 +0.8942 +0.8930 +0.8917 +0.8905 +0.8892 +0.8880 +0.8867 +0.8854 +0.8842 +0.8829 +0.8816 +0.8804 +0.8791 +0.8778 +0.8765 +0.8752 +0.8739 +0.8726 +0.8713 +0.8700 +0.8687 +0.8674 +0.8661 +0.8647 +0.8634 +0.8621 +0.8607 +0.8594 +0.8581 +0.8567 +0.8554 +0.8540 +0.8527 +0.8513 +0.8500 +0.8486 +0.8473 +0.8459 +0.8445 +0.8431 +0.8418 +0.8404 +0.8390 +0.8376 +0.8362 +0.8348 +0.8334 +0.8320 +0.8306 +0.8292 +0.8278 +0.8264 +0.8250 +0.8236 +0.8221 +0.8207 +0.8193 +0.8179 +0.8164 +0.8150 +0.8136 +0.8121 +0.8107 +0.8092 +0.8078 +0.8063 +0.8049 +0.8034 +0.8019 +0.8005 +0.7990 +0.7975 +0.7960 +0.7946 +0.7931 +0.7916 +0.7901 +0.7886 +0.7871 +0.7856 +0.7842 +0.7827 +0.7812 +0.7796 +0.7781 +0.7766 +0.7751 +0.7736 +0.7721 +0.7706 +0.7690 +0.7675 +0.7660 +0.7645 +0.7629 +0.7614 +0.7599 +0.7583 +0.7568 +0.7552 +0.7537 +0.7521 +0.7506 +0.7490 +0.7475 +0.7459 +0.7444 +0.7428 +0.7412 +0.7397 +0.7381 +0.7365 +0.7350 +0.7334 +0.7318 +0.7302 +0.7286 +0.7271 +0.7255 +0.7239 +0.7223 +0.7207 +0.7191 +0.7175 +0.7159 +0.7143 +0.7127 +0.7111 +0.7095 +0.7079 +0.7063 +0.7047 +0.7031 +0.7015 +0.6999 +0.6982 +0.6966 +0.6950 +0.6934 +0.6918 +0.6901 +0.6885 +0.6869 +0.6852 +0.6836 +0.6820 +0.6803 +0.6787 +0.6771 +0.6754 +0.6738 +0.6722 +0.6705 +0.6689 +0.6672 +0.6656 +0.6639 +0.6623 +0.6606 +0.6590 +0.6573 +0.6557 +0.6540 +0.6524 +0.6507 +0.6490 +0.6474 +0.6457 +0.6441 +0.6424 +0.6407 +0.6391 +0.6374 +0.6357 +0.6341 +0.6324 +0.6307 +0.6291 +0.6274 +0.6257 +0.6241 +0.6224 +0.6207 +0.6190 +0.6174 +0.6157 +0.6140 +0.6123 +0.6107 +0.6090 +0.6073 +0.6056 +0.6039 +0.6023 +0.6006 +0.5989 +0.5972 +0.5955 +0.5939 +0.5922 +0.5905 +0.5888 +0.5871 +0.5855 +0.5838 +0.5821 +0.5804 +0.5787 +0.5770 +0.5754 +0.5737 +0.5720 +0.5703 +0.5686 +0.5669 +0.5652 +0.5636 +0.5619 +0.5602 +0.5585 +0.5568 +0.5551 +0.5535 +0.5518 +0.5501 +0.5484 +0.5467 +0.5450 +0.5434 +0.5417 +0.5400 +0.5383 +0.5366 +0.5350 +0.5333 +0.5316 +0.5299 +0.5282 +0.5266 +0.5249 +0.5232 +0.5215 +0.5199 +0.5182 +0.5165 +0.5148 +0.5132 +0.5115 +0.5098 +0.5082 +0.5065 +0.5048 +0.5032 +0.5015 +0.4998 +0.4982 +0.4965 +0.4948 +0.4932 +0.4915 +0.4898 +0.4882 +0.4865 +0.4849 +0.4832 +0.4816 +0.4799 +0.4782 +0.4766 +0.4749 +0.4733 +0.4716 +0.4700 +0.4684 +0.4667 +0.4651 +0.4634 +0.4618 +0.4601 +0.4585 +0.4569 +0.4552 +0.4536 +0.4520 +0.4503 +0.4487 +0.4471 +0.4455 +0.4438 +0.4422 +0.4406 +0.4390 +0.4374 +0.4357 +0.4341 +0.4325 +0.4309 +0.4293 +0.4277 +0.4261 +0.4245 +0.4229 +0.4213 +0.4197 +0.4181 +0.4165 +0.4149 +0.4133 +0.4117 +0.4101 +0.4086 +0.4070 +0.4054 +0.4038 +0.4022 +0.4007 +0.3991 +0.3975 +0.3960 +0.3944 +0.3928 +0.3913 +0.3897 +0.3882 +0.3866 +0.3850 +0.3835 +0.3819 +0.3804 +0.3789 +0.3773 +0.3758 +0.3742 +0.3727 +0.3712 +0.3697 +0.3681 +0.3666 +0.3651 +0.3636 +0.3621 +0.3605 +0.3590 +0.3575 +0.3560 +0.3545 +0.3530 +0.3515 +0.3500 +0.3485 +0.3470 +0.3456 +0.3441 +0.3426 +0.3411 +0.3396 +0.3382 +0.3367 +0.3352 +0.3338 +0.3323 +0.3308 +0.3294 +0.3279 +0.3265 +0.3250 +0.3236 +0.3222 +0.3207 +0.3193 +0.3178 +0.3164 +0.3150 +0.3136 +0.3122 +0.3107 +0.3093 +0.3079 +0.3065 +0.3051 +0.3037 +0.3023 +0.3009 +0.2995 +0.2981 +0.2967 +0.2953 +0.2940 +0.2926 +0.2912 +0.2899 +0.2885 +0.2871 +0.2858 +0.2844 +0.2831 +0.2817 +0.2804 +0.2790 +0.2777 +0.2763 +0.2750 +0.2737 +0.2723 +0.2710 +0.2697 +0.2684 +0.2671 +0.2658 +0.2645 +0.2631 +0.2618 +0.2606 +0.2593 +0.2580 +0.2567 +0.2554 +0.2541 +0.2528 +0.2516 +0.2503 +0.2490 +0.2478 +0.2465 +0.2453 +0.2440 +0.2428 +0.2415 +0.2403 +0.2391 +0.2378 +0.2366 +0.2354 +0.2341 +0.2329 +0.2317 +0.2305 +0.2293 +0.2281 +0.2269 +0.2257 +0.2245 +0.2233 +0.2221 +0.2209 +0.2198 +0.2186 +0.2174 +0.2163 +0.2151 +0.2139 +0.2128 +0.2116 +0.2105 +0.2093 +0.2082 +0.2071 +0.2059 +0.2048 +0.2037 +0.2026 +0.2014 +0.2003 +0.1992 +0.1981 +0.1970 +0.1959 +0.1948 +0.1937 +0.1926 +0.1915 +0.1905 +0.1894 +0.1883 +0.1872 +0.1862 +0.1851 +0.1841 +0.1830 +0.1820 +0.1809 +0.1799 +0.1788 +0.1778 +0.1768 +0.1757 +0.1747 +0.1737 +0.1727 +0.1717 +0.1707 +0.1696 +0.1686 +0.1677 +0.1667 +0.1657 +0.1647 +0.1637 +0.1627 +0.1618 +0.1608 +0.1598 +0.1589 +0.1579 +0.1569 +0.1560 +0.1550 +0.1541 +0.1532 +0.1522 +0.1513 +0.1504 +0.1494 +0.1485 +0.1476 +0.1467 +0.1458 +0.1449 +0.1440 +0.1431 +0.1422 +0.1413 +0.1404 +0.1395 +0.1386 +0.1378 +0.1369 +0.1360 +0.1352 +0.1343 +0.1334 +0.1326 +0.1317 +0.1309 +0.1301 +0.1292 +0.1284 +0.1276 +0.1267 +0.1259 +0.1251 +0.1243 +0.1235 +0.1227 +0.1219 +0.1211 +0.1203 +0.1195 +0.1187 +0.1179 +0.1171 +0.1163 +0.1155 +0.1148 +0.1140 +0.1132 +0.1125 +0.1117 +0.1110 +0.1102 +0.1095 +0.1087 +0.1080 +0.1073 +0.1065 +0.1058 +0.1051 +0.1044 +0.1036 +0.1029 +0.1022 +0.1015 +0.1008 +0.1001 +0.0994 +0.0987 +0.0980 +0.0973 +0.0967 +0.0960 +0.0953 +0.0946 +0.0940 +0.0933 +0.0926 +0.0920 +0.0913 +0.0907 +0.0900 +0.0894 +0.0887 +0.0881 +0.0875 +0.0868 +0.0862 +0.0856 +0.0850 +0.0844 +0.0837 +0.0831 +0.0825 +0.0819 +0.0813 +0.0807 +0.0801 +0.0795 +0.0789 +0.0784 +0.0778 +0.0772 +0.0766 +0.0761 +0.0755 +0.0749 +0.0744 +0.0738 +0.0732 +0.0727 +0.0721 +0.0716 +0.0711 +0.0705 +0.0700 +0.0694 +0.0689 +0.0684 +0.0679 +0.0673 +0.0668 +0.0663 +0.0658 +0.0653 +0.0648 +0.0643 +0.0638 +0.0633 +0.0628 +0.0623 +0.0618 +0.0613 +0.0608 +0.0604 +0.0599 +0.0594 +0.0589 +0.0585 +0.0580 +0.0575 +0.0571 +0.0566 +0.0562 +0.0557 +0.0553 +0.0548 +0.0544 +0.0539 +0.0535 +0.0531 +0.0526 +0.0522 +0.0518 +0.0514 +0.0509 +0.0505 +0.0501 +0.0497 +0.0493 +0.0489 +0.0485 +0.0481 +0.0477 +0.0473 +0.0469 +0.0465 +0.0461 +0.0457 +0.0453 +0.0450 +0.0446 +0.0442 +0.0438 +0.0435 +0.0431 +0.0427 +0.0424 +0.0420 +0.0416 +0.0413 +0.0409 +0.0406 +0.0402 +0.0399 +0.0395 +0.0392 +0.0389 +0.0385 +0.0382 +0.0379 +0.0375 +0.0372 +0.0369 +0.0365 +0.0362 +0.0359 +0.0356 +0.0353 +0.0350 +0.0347 +0.0343 +0.0340 +0.0337 +0.0334 +0.0331 +0.0328 +0.0325 +0.0323 +0.0320 +0.0317 +0.0314 +0.0311 +0.0308 +0.0305 +0.0303 +0.0300 +0.0297 +0.0295 +0.0292 +0.0289 +0.0286 +0.0284 +0.0281 +0.0279 +0.0276 +0.0274 +0.0271 +0.0268 +0.0266 +0.0264 +0.0261 +0.0259 +0.0256 +0.0254 +0.0251 +0.0249 +0.0247 +0.0244 +0.0242 +0.0240 +0.0237 +0.0235 +0.0233 +0.0231 +0.0229 +0.0226 +0.0224 +0.0222 +0.0220 +0.0218 +0.0216 +0.0214 +0.0212 +0.0210 +0.0207 +0.0205 +0.0203 +0.0201 +0.0200 +0.0198 +0.0196 +0.0194 +0.0192 +0.0190 +0.0188 +0.0186 +0.0184 +0.0182 +0.0181 +0.0179 +0.0177 +0.0175 +0.0174 +0.0172 +0.0170 +0.0168 +0.0167 +0.0165 +0.0163 +0.0162 +0.0160 +0.0158 +0.0157 +0.0155 +0.0154 +0.0152 +0.0151 +0.0149 +0.0147 +0.0146 +0.0144 +0.0143 +0.0142 +0.0140 +0.0139 +0.0137 +0.0136 +0.0134 +0.0133 +0.0132 +0.0130 +0.0129 +0.0127 +0.0126 +0.0125 +0.0123 +0.0122 +0.0121 +0.0120 +0.0118 +0.0117 +0.0116 +0.0115 +0.0113 +0.0112 +0.0111 +0.0110 +0.0109 +0.0107 +0.0106 +0.0105 +0.0104 +0.0103 +0.0102 +0.0101 +0.0100 +0.0098 +0.0097 +0.0096 +0.0095 +0.0094 +0.0093 +0.0092 +0.0091 +0.0090 +0.0089 +0.0088 +0.0087 +0.0086 +0.0085 +0.0084 +0.0083 +0.0082 +0.0082 +0.0081 +0.0080 +0.0079 +0.0078 +0.0077 +0.0076 +0.0075 +0.0074 +0.0074 +0.0073 +0.0072 +0.0071 +0.0070 +0.0070 +0.0069 +0.0068 +0.0067 +0.0066 +0.0066 +0.0065 +0.0064 +0.0063 +0.0063 +0.0062 +0.0061 +0.0061 +0.0060 +0.0059 +0.0058 +0.0058 +0.0057 +0.0056 +0.0056 +0.0055 +0.0054 +0.0054 +0.0053 +0.0053 +0.0052 +0.0051 +0.0051 +0.0050 +0.0049 +0.0049 +0.0048 +0.0048 +0.0047 +0.0047 \ No newline at end of file diff --git a/transformers/diffusion/tokenizer.cpp b/transformers/diffusion/tokenizer.cpp index b1881fafc..f64e982ef 100644 --- a/transformers/diffusion/tokenizer.cpp +++ b/transformers/diffusion/tokenizer.cpp @@ -16,7 +16,7 @@ namespace diffusion { bool BertTokenizer::load(const std::string& dictPath) { std::ifstream dictFile(dictPath + "/vocab.txt"); - if(dictFile.is_open()) { + if(!dictFile.is_open()) { MNN_ERROR("tokenize load error, vocab.txt not found in %s\n", dictPath.c_str()); return false; } diff --git a/transformers/llm/engine/CMakeLists.txt b/transformers/llm/engine/CMakeLists.txt index 25778d513..767cc272e 100644 --- a/transformers/llm/engine/CMakeLists.txt +++ b/transformers/llm/engine/CMakeLists.txt @@ -9,13 +9,19 @@ if (MSVC) add_library(llm STATIC ${SRCS}) target_link_libraries(llm ${MNN_DEPS}) else() - # compile dynamic so, support Linux/Mac - add_library(llm SHARED ${SRCS}) - set_target_properties(llm PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) - target_link_libraries(llm ${MNN_DEPS}) + if (MNN_SEP_BUILD) + if (MNN_BUILD_SHARED_LIBS) + # compile dynamic so, support Linux/Mac + add_library(llm SHARED ${SRCS}) + set_target_properties(llm PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) + target_link_libraries(llm ${MNN_DEPS}) + else() + add_library(llm STATIC ${SRCS}) + endif() + else() + add_library(llm OBJECT ${SRCS}) + endif() endif() -target_compile_features(llm PRIVATE cxx_std_17) add_executable(llm_demo ${CMAKE_CURRENT_LIST_DIR}/llm_demo.cpp) -target_compile_features(llm_demo PRIVATE cxx_std_17) target_link_libraries(llm_demo llm) \ No newline at end of file diff --git a/transformers/llm/engine/include/llm.hpp b/transformers/llm/engine/include/llm.hpp index 4754010cf..71c3f00fd 100644 --- a/transformers/llm/engine/include/llm.hpp +++ b/transformers/llm/engine/include/llm.hpp @@ -93,32 +93,44 @@ class rapid_json_wrapper { return json_wrapper; } - template - T value(const char* key, const T& defualt_value) const { + int value(const char* key, const int& default_value) const { if (document.HasMember(key)) { const auto& value = document[key]; - if constexpr (std::is_same::value) { - if (value.IsInt()) return value.GetInt(); - } else if constexpr (std::is_same::value || std::is_same::value) { - if (value.IsString()) return value.GetString(); - } else if constexpr (std::is_same::value) { - if (value.IsBool()) return value.GetBool(); - } else if constexpr (std::is_same>::value) { - if (value.IsArray()) { - std::vector result; - for (auto& v : value.GetArray()) { - if (v.IsInt()) { - result.push_back(v.GetInt()); - } + if (value.IsInt()) return value.GetInt(); + } + return default_value; + } + bool value(const char* key, const bool& default_value) const { + if (document.HasMember(key)) { + const auto& value = document[key]; + if (value.IsBool()) return value.GetBool(); + } + return default_value; + } + std::string value(const char* key, const std::string& default_value) const { + if (document.HasMember(key)) { + const auto& value = document[key]; + if (value.IsString()) return value.GetString(); + } + return default_value; + } + std::vector value(const char* key, const std::vector& default_value) const { + if (document.HasMember(key)) { + const auto& value = document[key]; + if (value.IsArray()) { + std::vector result; + for (auto& v : value.GetArray()) { + if (v.IsInt()) { + result.push_back(v.GetInt()); } - return result; } + return result; } } - return defualt_value; + return default_value; } - std::string value(const char key[], const char defualt_value[]) const { - return value(key, std::string(defualt_value)); + std::string value(const char key[], const char default_value[]) const { + return value(key, std::string(default_value)); } }; @@ -251,6 +263,10 @@ class LlmConfig { return llm_config_.value("attention_mask", "int"); } + std::string chat_template() const { + return llm_config_.value("chat_template", ""); + } + std::string prompt_template() const { return llm_config_.value("prompt_template", ""); } @@ -258,6 +274,7 @@ class LlmConfig { }; class MNN_PUBLIC Llm { + using PromptItem = std::pair; // public: Llm(std::shared_ptr config) : config_(config) {} virtual ~Llm(); @@ -267,8 +284,10 @@ class MNN_PUBLIC Llm { virtual void load(); VARP forward(const std::vector& input_ids); int sample(VARP logits, const std::vector& pre_ids); - std::string apply_chat_template(const std::string& input_str) const; - std::string response(const std::string& input_str, std::ostream* os = &std::cout, const char* end_with = nullptr); + std::string apply_prompt_template(const std::string& user_content) const; + std::string apply_chat_template(const std::vector& chat_prompts) const; + std::string response(const std::string& user_content, std::ostream* os = &std::cout, const char* end_with = nullptr); + std::string response(const std::vector& chat_prompts, std::ostream* os = &std::cout, const char* end_with = nullptr); void generate_init(); std::string generate(const std::vector& input_ids, std::ostream* os, const char* end_with); std::vector generate(const std::vector& input_ids, int max_new_tokens = -1); diff --git a/transformers/llm/engine/include/tokenizer.hpp b/transformers/llm/engine/include/tokenizer.hpp index 16d10861d..e30cd980e 100644 --- a/transformers/llm/engine/include/tokenizer.hpp +++ b/transformers/llm/engine/include/tokenizer.hpp @@ -13,7 +13,54 @@ #include #include #include -#include +// #include +#include + +// std::string_view impl in c++11 start +class string_view_ { +public: + string_view_() : data_(nullptr), size_(0) {} + string_view_(const char* data) : data_(data), size_(std::strlen(data)) {} + string_view_(const char* data, std::size_t size) : data_(data), size_(size) {} + string_view_(const std::string& str) : data_(str.data()), size_(str.size()) {} + constexpr string_view_(const string_view_&) noexcept = default; + string_view_& operator=(const string_view_&) noexcept = default; + const char& operator[](size_t pos) const { return data_[pos]; } + constexpr const char* data() const noexcept { return data_; } + constexpr std::size_t size() const noexcept { return size_; } + constexpr bool empty() const { return size_ == 0; } + std::string to_string() const { return std::string(data_, size_); } + bool operator==(const string_view_& other) const noexcept { + return size_ == other.size_ && strncmp(data_, other.data_, size_) == 0; + } + void remove_prefix(size_t n) { + if (n < size_) { + data_ += n; + size_ -= n; + } else { + data_ = ""; + size_ = 0; + } + } +private: + const char* data_; + std::size_t size_ = 0; +}; + +namespace std { + template<> + class hash { + public: + size_t operator()(const string_view_& sv) const { + size_t result = 0; + for (size_t i = 0; i < sv.size(); ++i) { + result = (result * 31) + static_cast(sv[i]); + } + return result; + } + }; +} +// std::string_view impl in c++11 end class Tokenizer { public: @@ -28,6 +75,7 @@ class Tokenizer { virtual ~Tokenizer() = default; static Tokenizer* createTokenizer(const std::string& filename); bool is_stop(int token); + bool is_special(int token); std::vector encode(const std::string& str); virtual std::string decode(int id) = 0; protected: @@ -65,8 +113,10 @@ class Sentencepiece : public Tokenizer { std::string piece; float score; PieceType type = PieceType::NORMAL; + SentencePiece() {} + SentencePiece(const std::string& p, float s, PieceType t) : piece(p), score(s), type(t) {} }; - using EncodeResult = std::vector>; + using EncodeResult = std::vector>; private: // model train type ModelType type_ = BPE; @@ -86,7 +136,7 @@ class Sentencepiece : public Tokenizer { bool is_control(int id) const; int piece_to_id(const std::string& w) const; std::string byte_to_piece(unsigned char c) const; - EncodeResult bpe_encode(std::string_view str, float alpha = 0.f); + EncodeResult bpe_encode(string_view_ str, float alpha = 0.f); }; class Tiktoken : public Tokenizer { diff --git a/transformers/llm/engine/llm_demo.cpp b/transformers/llm/engine/llm_demo.cpp index 3c6512661..4edc7731d 100644 --- a/transformers/llm/engine/llm_demo.cpp +++ b/transformers/llm/engine/llm_demo.cpp @@ -187,6 +187,7 @@ int main(int argc, const char* argv[]) { } if (argc < 3) { llm->chat(); + return 0; } std::string prompt_file = argv[2]; return eval(llm.get(), prompt_file); diff --git a/transformers/llm/engine/src/llm.cpp b/transformers/llm/engine/src/llm.cpp index 86ff80596..3838d8538 100644 --- a/transformers/llm/engine/src/llm.cpp +++ b/transformers/llm/engine/src/llm.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -180,17 +181,18 @@ VARP Llm::forward(const std::vector& input_ids) { } int Llm::sample(VARP logits, const std::vector& pre_ids) { + std::unordered_set ids_set(pre_ids.begin(), pre_ids.end()); auto scores = (float*)(logits->readMap()); auto size = logits->getInfo()->size; - float max_score = 0; - int token_id = 0; // repetition penalty const float repetition_penalty = 1.1; - for (auto id : pre_ids) { + for (auto id : ids_set) { float score = scores[id]; scores[id] = score < 0 ? score * repetition_penalty : score / repetition_penalty; } // argmax + float max_score = 0; + int token_id = 0; for (int i = 0; i < size; i++) { float score = scores[i]; if (score > max_score) { @@ -201,31 +203,60 @@ int Llm::sample(VARP logits, const std::vector& pre_ids) { return token_id; } -std::string Llm::apply_chat_template(const std::string& input_str) const { - auto prompt = config_->prompt_template(); - if (prompt.empty()) return input_str; +static std::string apply_template(std::string prompt_template, const std::string& content, const std::string& role = "") { + if (prompt_template.empty()) return content; + if (!role.empty()) { + const std::string placeholder = "%r"; + size_t start_pos = prompt_template.find(placeholder); + if (start_pos == std::string::npos) return content; + prompt_template.replace(start_pos, placeholder.length(), role); + } const std::string placeholder = "%s"; - size_t start_pos = prompt.find(placeholder); - if (start_pos == std::string::npos) return input_str; - prompt.replace(start_pos, placeholder.length(), input_str); - return prompt; + size_t start_pos = prompt_template.find(placeholder); + if (start_pos == std::string::npos) return content; + prompt_template.replace(start_pos, placeholder.length(), content); + return prompt_template; +} + +std::string Llm::apply_prompt_template(const std::string& user_content) const { + auto chat_prompt = config_->prompt_template(); + return apply_template(chat_prompt, user_content); +} + +std::string Llm::apply_chat_template(const std::vector& chat_prompts) const { + auto chat_template = config_->chat_template(); + std::string prompt_result; + auto iter = chat_prompts.begin(); + for (; iter != chat_prompts.end() - 1; ++iter) { + prompt_result += apply_template(chat_template, iter->second, iter->first); + } + if (iter->first == "user") { + prompt_result += apply_prompt_template(iter->second); + } else { + prompt_result += apply_template(chat_template, iter->second, iter->first); + } + return prompt_result; } void Llm::chat() { + std::vector history; + history.push_back(std::make_pair("system", "You are a helpful assistant.")); while (true) { std::cout << "\nQ: "; - std::string input_str; - std::cin >> input_str; - if (input_str == "/exit") { + std::string user_str; + std::cin >> user_str; + if (user_str == "/exit") { break; } - if (input_str == "/reset") { - // reset(); + if (user_str == "/reset") { + history.resize(1); std::cout << "\nA: reset done." << std::endl; continue; } std::cout << "\nA: " << std::flush; - response(input_str); + history.emplace_back(std::make_pair("user", user_str)); + auto assistant_str = response(history); + history.emplace_back(std::make_pair("assistant", assistant_str)); std::cout << std::endl; } } @@ -316,18 +347,28 @@ std::string Llm::generate(const std::vector& input_ids, std::ostream* os, c return output_str; } -std::vector Llm::tokenizer(const std::string& query) { - auto prompt = apply_chat_template(query); +std::vector Llm::tokenizer(const std::string& user_content) { + auto prompt = apply_prompt_template(user_content); auto input_ids = tokenizer_->encode(prompt); return input_ids; } -std::string Llm::response(const std::string& query, std::ostream* os, const char* end_with) { +std::string Llm::response(const std::string& user_content, std::ostream* os, const char* end_with) { generate_init(); if (!end_with) { end_with = "\n"; } - auto input_ids = tokenizer(query); + auto input_ids = tokenizer(user_content); return generate(input_ids, os, end_with); } + +std::string Llm::response(const std::vector& chat_prompts, std::ostream* os, const char* end_with) { + if (chat_prompts.empty()) { return ""; } + generate_init(); + if (!end_with) { end_with = "\n"; } + auto prompt = apply_chat_template(chat_prompts); + auto input_ids = tokenizer_->encode(prompt); + return generate(input_ids, os, end_with); +} + Llm::~Llm() { #if DEBUG_MODE==1 if (nullptr != gTimeTraceInfo) { @@ -522,7 +563,7 @@ std::vector Lvlm::url_encode(const std::string& url) { } std::vector Lvlm::tokenizer(const std::string& query) { - auto prompt = apply_chat_template(query); + auto prompt = apply_prompt_template(query); // split query std::regex img_regex("(.*?)"); std::string::const_iterator searchStart(prompt.cbegin()); @@ -666,7 +707,7 @@ std::vector Embedding::tokenizer(const std::string& query) { if (query.size() <= 256) { prompt = "为这个句子生成表示以用于检索相关文章:" + query; } - prompt = apply_chat_template(prompt); + prompt = apply_prompt_template(prompt); auto ids = tokenizer_->encode(prompt); return ids; } diff --git a/transformers/llm/engine/src/tokenizer.cpp b/transformers/llm/engine/src/tokenizer.cpp index d6f6490c8..f0350adc9 100644 --- a/transformers/llm/engine/src/tokenizer.cpp +++ b/transformers/llm/engine/src/tokenizer.cpp @@ -128,6 +128,10 @@ bool Tokenizer::is_stop(int token) { return std::find(stop_tokens_.begin(), stop_tokens_.end(), token) != stop_tokens_.end(); } +bool Tokenizer::is_special(int token) { + return std::find(special_tokens_.begin(), special_tokens_.end(), token) != special_tokens_.end(); +} + void Tokenizer::load_special(std::ifstream& tok_file) { std::string line; std::getline(tok_file, line); @@ -201,7 +205,7 @@ bool Sentencepiece::load_vocab(std::ifstream& tok_file) { line_str >> token >> score >> type; token = base64_decode(token); auto piece_type = static_cast(type); - SentencePiece piece {token, score, piece_type}; + SentencePiece piece = {token, score, piece_type}; sentence_pieces_[index] = std::move(piece); if (piece_type == PieceType::NORMAL) { pieces_.insert({token, index}); @@ -236,7 +240,7 @@ std::string Sentencepiece::byte_to_piece(unsigned char c) const { } // ref: https://github.com/google/sentencepiece/blob/master/src/bpe_model.cc -Sentencepiece::EncodeResult Sentencepiece::bpe_encode(std::string_view normalized, float alpha) { +Sentencepiece::EncodeResult Sentencepiece::bpe_encode(string_view_ normalized, float alpha) { // util class begin struct SymbolPair { int left; // left index of this pair @@ -256,7 +260,7 @@ Sentencepiece::EncodeResult Sentencepiece::bpe_encode(std::string_view normalize int prev; // prev index of this symbol. -1 for BOS. int next; // next index of tihs symbol. -1 for EOS. bool freeze = false; // this symbol is never be merged. - std::string_view piece; + string_view_ piece; }; // util class end @@ -265,7 +269,7 @@ Sentencepiece::EncodeResult Sentencepiece::bpe_encode(std::string_view normalize std::vector symbols; symbols.reserve(normalized.size()); // Reverse merge rules. key: merged symbol, value: pair of original symbols. - std::unordered_map> rev_merge; + std::unordered_map> rev_merge; // SymbolPair holder. std::vector> symbol_pair_holder; // Lookup new symbol pair at [left, right] and inserts it to agenda. @@ -273,8 +277,8 @@ Sentencepiece::EncodeResult Sentencepiece::bpe_encode(std::string_view normalize if (left == -1 || right == -1 || symbols[left].freeze || symbols[right].freeze) { return; } - const std::string_view piece(symbols[left].piece.data(), symbols[left].piece.size() + symbols[right].piece.size()); - std::string piece_str(piece); + const string_view_ piece(symbols[left].piece.data(), symbols[left].piece.size() + symbols[right].piece.size()); + std::string piece_str(piece.to_string()); const auto it = pieces_.find(piece_str); if (it == pieces_.end()) { return; @@ -298,7 +302,7 @@ Sentencepiece::EncodeResult Sentencepiece::bpe_encode(std::string_view normalize Symbol s; // const int mblen = matcher_->PrefixMatch(normalized, &s.freeze); int mblen = std::min(normalized.size(), one_char_len(normalized.data())); - s.piece = std::string_view(normalized.data(), mblen); + s.piece = string_view_(normalized.data(), mblen); s.prev = index == 0 ? -1 : index - 1; normalized.remove_prefix(mblen); s.next = normalized.empty() ? -1 : index + 1; @@ -338,7 +342,7 @@ Sentencepiece::EncodeResult Sentencepiece::bpe_encode(std::string_view normalize if (skip_merge()) continue; // Replaces symbols with `top` rule. - symbols[top->left].piece = std::string_view( + symbols[top->left].piece = string_view_( symbols[top->left].piece.data(), symbols[top->left].piece.size() + symbols[top->right].piece.size()); @@ -347,16 +351,16 @@ Sentencepiece::EncodeResult Sentencepiece::bpe_encode(std::string_view normalize if (symbols[top->right].next >= 0) { symbols[symbols[top->right].next].prev = top->left; } - symbols[top->right].piece = std::string_view(""); + symbols[top->right].piece = string_view_(""); // Adds new symbol pairs which are newly added after symbol replacement. MaybeAddNewSymbolPair(symbols[top->left].prev, top->left); MaybeAddNewSymbolPair(top->left, symbols[top->left].next); } - std::function resegment; - resegment = [this, &resegment, &rev_merge](std::string_view w, EncodeResult *output) -> void { - std::string w_str(w); + std::function resegment; + resegment = [this, &resegment, &rev_merge](string_view_ w, EncodeResult *output) -> void { + std::string w_str(w.to_string()); const int id = piece_to_id(w_str); // std::cout << "piece: " << w << ", id = " << id << std::endl; if (id == -1 || !is_unused(id)) { @@ -385,7 +389,7 @@ void Sentencepiece::encode(const std::string& str, std::vector& ids) { auto result = bpe_encode(str); size_t consumed = 0; for (const auto &p : result) { - const std::string_view w = p.first; // piece + const string_view_ w = p.first; // piece const int id = p.second; // id const bool is_unk = (id == unk_id_); if (is_unk && byte_fall_back_) { diff --git a/transformers/llm/eval/evaluate_chat_ceval.py b/transformers/llm/eval/evaluate_chat_ceval.py new file mode 100644 index 000000000..50d47f35e --- /dev/null +++ b/transformers/llm/eval/evaluate_chat_ceval.py @@ -0,0 +1,508 @@ +import os +import argparse +import re +import torch +import pandas as pd +from thefuzz import process +from tqdm import tqdm +from transformers import AutoTokenizer +import MNN.llm as mnnllm + +''' +export HF_ENDPOINT=https://hf-mirror.com +wget https://huggingface.co/datasets/ceval/ceval-exam/resolve/main/ceval-exam.zip +mkdir data/ceval +mv ceval-exam.zip data/ceval +cd data/ceval; unzip ceval-exam.zip +cd ../../ + +pip install thefuzz +python eval/evaluate_chat_ceval.py -d data/ceval +''' + +def load_models_tokenizer(args): + tokenizer = AutoTokenizer.from_pretrained( + args.checkpoint_path, trust_remote_code=True + ) + model = mnnllm.create(args.mnn_path) + model.load() + return model, tokenizer + +def process_before_extraction(gen, question, choice_dict): + # Example Prompt: + # 关于传输层的面向连接服务的特性是____。 + # A. 既不保证可靠,也不保证按序交付 + # B. 不保证可靠,但保证按序交付 + # C. 保证可靠,但不保证按序交付 + # D. 既保证可靠,也保证按序交付 + # Example Model Output: + # 关于传输层的面向连接服务的特性是既保证可靠,也保证按序交付 + # Processed Output: + # 答案是D + + question_split = question.rstrip("。").split("。")[-1].split("_") + + # replacing the question + if len(question_split[0].strip()) > 4: + gen = gen.replace(question_split[0], "答案是") + if len(question_split[-1].strip()) > 4: + gen = gen.replace(question_split[-1], "") + + # replace the choice by letter in the generated sentence + # from longest one to shortest one + for key, val in sorted(choice_dict.items(), key=lambda x: len(x[1]), reverse=True): + gen = gen.replace(val.rstrip("。"), key) + + return gen + + +def count_substr(gen, pattern): + return len(re.findall(pattern, gen)) + + +def extract_choice(gen, prompt, choice_list): + # 答案是A | 选项是A | 应该选A选项 + res = re.search( + r"(?:(?:选|选择|选定)[::]?\s*|(?:(?:答案|选项)(?![^ABCD]{0,10}?(?:不|非)[^ABCD]{0,10}?(?:是|选|为|:|:|】))[^ABCD]{0,10}?(?:是|选|为|:|:|】))[^ABCD]{0,10}?)(A|B|C|D)(?:选项)?(?:\)|。|\.|,|,|.|、|A|B|C|D|$|:|:|\)|))", + gen, + ) + + # A选项正确 | A选项符合题意 + if res is None: + res = re.search( + r"(A|B|C|D)(?:选?项)?(?![^ABCD]{0,4}?(?:不|非)[^ABCD]{0,4}?(?:正确|对[的,。:]|符合))[^ABCD]{0,4}?(?:正确|对[的,。:]|符合)", + gen, + ) + + # 直接输出 A + if res is None: + res = re.search(r"^[\((]?(A|B|C|D)(?:。|\)|)|\.|,|,|.|:|:|$)", gen) + + # 获取第一个出现的字母 + if res is None: + res = re.search(r"(? 0: + print("Hard acc:%.2f " % (hard_acc_sum / hard_cnt)) + print("AVERAGE acc:%.2f " % (acc_sum / cnt)) + + +''' +TASK_NAME_MAPPING = { + "computer_network": ["Computer Network", "\u8ba1\u7b97\u673a\u7f51\u7edc", "STEM"], + "operating_system": ["Operating System", "\u64cd\u4f5c\u7cfb\u7edf", "STEM"], + "computer_architecture": [ + "Computer Architecture", + "\u8ba1\u7b97\u673a\u7ec4\u6210", + "STEM", + ], + "college_programming": ["College Programming", "\u5927\u5b66\u7f16\u7a0b", "STEM"], + "college_physics": ["College Physics", "\u5927\u5b66\u7269\u7406", "STEM"], + "college_chemistry": ["College Chemistry", "\u5927\u5b66\u5316\u5b66", "STEM"], + "advanced_mathematics": [ + "Advanced Mathematics", + "\u9ad8\u7b49\u6570\u5b66", + "STEM", + ], + "probability_and_statistics": [ + "Probability and Statistics", + "\u6982\u7387\u7edf\u8ba1", + "STEM", + ], + "discrete_mathematics": [ + "Discrete Mathematics", + "\u79bb\u6563\u6570\u5b66", + "STEM", + ], + "electrical_engineer": [ + "Electrical Engineer", + "\u6ce8\u518c\u7535\u6c14\u5de5\u7a0b\u5e08", + "STEM", + ], + "metrology_engineer": [ + "Metrology Engineer", + "\u6ce8\u518c\u8ba1\u91cf\u5e08", + "STEM", + ], + "high_school_mathematics": [ + "High School Mathematics", + "\u9ad8\u4e2d\u6570\u5b66", + "STEM", + ], + "high_school_physics": ["High School Physics", "\u9ad8\u4e2d\u7269\u7406", "STEM"], + "high_school_chemistry": [ + "High School Chemistry", + "\u9ad8\u4e2d\u5316\u5b66", + "STEM", + ], + "high_school_biology": ["High School Biology", "\u9ad8\u4e2d\u751f\u7269", "STEM"], + "middle_school_mathematics": [ + "Middle School Mathematics", + "\u521d\u4e2d\u6570\u5b66", + "STEM", + ], + "middle_school_biology": [ + "Middle School Biology", + "\u521d\u4e2d\u751f\u7269", + "STEM", + ], + "middle_school_physics": [ + "Middle School Physics", + "\u521d\u4e2d\u7269\u7406", + "STEM", + ], + "middle_school_chemistry": [ + "Middle School Chemistry", + "\u521d\u4e2d\u5316\u5b66", + "STEM", + ], + "veterinary_medicine": ["Veterinary Medicine", "\u517d\u533b\u5b66", "STEM"], + "college_economics": [ + "College Economics", + "\u5927\u5b66\u7ecf\u6d4e\u5b66", + "Social Science", + ], + "business_administration": [ + "Business Administration", + "\u5de5\u5546\u7ba1\u7406", + "Social Science", + ], + "marxism": [ + "Marxism", + "\u9a6c\u514b\u601d\u4e3b\u4e49\u57fa\u672c\u539f\u7406", + "Social Science", + ], + "mao_zedong_thought": [ + "Mao Zedong Thought", + "\u6bdb\u6cfd\u4e1c\u601d\u60f3\u548c\u4e2d\u56fd\u7279\u8272\u793e\u4f1a\u4e3b\u4e49\u7406\u8bba\u4f53\u7cfb\u6982\u8bba", + "Social Science", + ], + "education_science": ["Education Science", "\u6559\u80b2\u5b66", "Social Science"], + "teacher_qualification": [ + "Teacher Qualification", + "\u6559\u5e08\u8d44\u683c", + "Social Science", + ], + "high_school_politics": [ + "High School Politics", + "\u9ad8\u4e2d\u653f\u6cbb", + "Social Science", + ], + "high_school_geography": [ + "High School Geography", + "\u9ad8\u4e2d\u5730\u7406", + "Social Science", + ], + "middle_school_politics": [ + "Middle School Politics", + "\u521d\u4e2d\u653f\u6cbb", + "Social Science", + ], + "middle_school_geography": [ + "Middle School Geography", + "\u521d\u4e2d\u5730\u7406", + "Social Science", + ], + "modern_chinese_history": [ + "Modern Chinese History", + "\u8fd1\u4ee3\u53f2\u7eb2\u8981", + "Humanities", + ], + "ideological_and_moral_cultivation": [ + "Ideological and Moral Cultivation", + "\u601d\u60f3\u9053\u5fb7\u4fee\u517b\u4e0e\u6cd5\u5f8b\u57fa\u7840", + "Humanities", + ], + "logic": ["Logic", "\u903b\u8f91\u5b66", "Humanities"], + "law": ["Law", "\u6cd5\u5b66", "Humanities"], + "chinese_language_and_literature": [ + "Chinese Language and Literature", + "\u4e2d\u56fd\u8bed\u8a00\u6587\u5b66", + "Humanities", + ], + "art_studies": ["Art Studies", "\u827a\u672f\u5b66", "Humanities"], + "professional_tour_guide": [ + "Professional Tour Guide", + "\u5bfc\u6e38\u8d44\u683c", + "Humanities", + ], + "legal_professional": [ + "Legal Professional", + "\u6cd5\u5f8b\u804c\u4e1a\u8d44\u683c", + "Humanities", + ], + "high_school_chinese": [ + "High School Chinese", + "\u9ad8\u4e2d\u8bed\u6587", + "Humanities", + ], + "high_school_history": [ + "High School History", + "\u9ad8\u4e2d\u5386\u53f2", + "Humanities", + ], + "middle_school_history": [ + "Middle School History", + "\u521d\u4e2d\u5386\u53f2", + "Humanities", + ], + "civil_servant": ["Civil Servant", "\u516c\u52a1\u5458", "Other"], + "sports_science": ["Sports Science", "\u4f53\u80b2\u5b66", "Other"], + "plant_protection": ["Plant Protection", "\u690d\u7269\u4fdd\u62a4", "Other"], + "basic_medicine": ["Basic Medicine", "\u57fa\u7840\u533b\u5b66", "Other"], + "clinical_medicine": ["Clinical Medicine", "\u4e34\u5e8a\u533b\u5b66", "Other"], + "urban_and_rural_planner": [ + "Urban and Rural Planner", + "\u6ce8\u518c\u57ce\u4e61\u89c4\u5212\u5e08", + "Other", + ], + "accountant": ["Accountant", "\u6ce8\u518c\u4f1a\u8ba1\u5e08", "Other"], + "fire_engineer": [ + "Fire Engineer", + "\u6ce8\u518c\u6d88\u9632\u5de5\u7a0b\u5e08", + "Other", + ], + "environmental_impact_assessment_engineer": [ + "Environmental Impact Assessment Engineer", + "\u73af\u5883\u5f71\u54cd\u8bc4\u4ef7\u5de5\u7a0b\u5e08", + "Other", + ], + "tax_accountant": ["Tax Accountant", "\u7a0e\u52a1\u5e08", "Other"], + "physician": ["Physician", "\u533b\u5e08\u8d44\u683c", "Other"], +} +''' +TASK_NAME_MAPPING = { + "teacher_qualification": [ + "Teacher Qualification", + "\u6559\u5e08\u8d44\u683c", + "Social Science", + ], + "marxism": [ + "Marxism", + "\u9a6c\u514b\u601d\u4e3b\u4e49\u57fa\u672c\u539f\u7406", + "Social Science", + ], + "middle_school_politics": [ + "Middle School Politics", + "\u521d\u4e2d\u653f\u6cbb", + "Social Science", + ], + "middle_school_history": [ + "Middle School History", + "\u521d\u4e2d\u5386\u53f2", + "Humanities", + ], + "middle_school_chemistry": [ + "Middle School Chemistry", + "\u521d\u4e2d\u5316\u5b66", + "STEM", + ], + "modern_chinese_history": [ + "Modern Chinese History", + "\u8fd1\u4ee3\u53f2\u7eb2\u8981", + "Humanities", + ], +} +hard_list = [ + "advanced_mathematics", + "discrete_mathematics", + "probability_and_statistics", + "college_physics", + "college_chemistry", + "high_school_mathematics", + "high_school_physics", + "high_school_chemistry", +] +choices = ["A", "B", "C", "D"] + + +def main(args): + print("loading model weights") + if args.checkpoint_path: + model, tokenizer = load_models_tokenizer(args) + else: + model, tokenizer = None, None + print("model loaded") + dev_result = {} + for subject_name in tqdm(TASK_NAME_MAPPING.keys()): + val_file_path = os.path.join( + args.eval_data_path, "val", f"{subject_name}_val.csv" + ) + val_df = pd.read_csv(val_file_path) + + score = eval_subject( + model, + tokenizer, + subject_name, + val_df, + save_result_dir="outs_chat/ceval_eval_result", + overwrite=args.overwrite, + ) + dev_result[subject_name] = score + print(dev_result) + cal_ceval(dev_result) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Test HF checkpoint.") + parser.add_argument( + "-c", + "--checkpoint-path", + type=str, + help="Checkpoint path", + default="/Users/wangzhaode/Qwen1_5-1_8B-Chat", + ) + parser.add_argument( + "-m", + "--mnn-path", + type=str, + help="mnn model path", + default="/home/yanxing/data/qwen-1.8b-int4/config.json", + ) + + # Provide extra arguments required for tasks + group = parser.add_argument_group(title="Evaluation options") + group.add_argument( + "-d", "--eval_data_path", type=str, required=True, help="Path to eval data" + ) + group.add_argument( + "--debug", action="store_true", default=False, help="Print infos." + ) + group.add_argument( + "--overwrite", + action="store_true", + default=False, + help="Overwrite existed results", + ) + + args = parser.parse_args() + + main(args)