From 0efc96105eb331fcc5c7584cbb4f8154291cdab0 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 3 Nov 2023 06:46:41 -0700 Subject: [PATCH 001/581] simplify: Fix TRACE output of resulting triangle count Everywhere else the debug output seems correct but here we forgot to convert from index count to triangle count. --- src/simplifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 5ba8570076..2033d190b8 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -1611,7 +1611,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic } #if TRACE - printf("result: %d triangles, error: %e; total %d passes\n", int(result_count), sqrtf(result_error), int(pass_count)); + printf("result: %d triangles, error: %e; total %d passes\n", int(result_count / 3), sqrtf(result_error), int(pass_count)); #endif #ifndef NDEBUG From d57567f7b19762d47ca13bc1d84158db8851b1dd Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 11 Nov 2023 06:45:30 -0800 Subject: [PATCH 002/581] gltfpack: Refactor floating-point stream encoding The only difference between position and texture coordinate floating point encoding was component count and min_exp cutoff; this change extracts the code into a separate function so that it's easier to reuse. --- gltf/stream.cpp | 144 ++++++++++++++++++------------------------------ 1 file changed, 55 insertions(+), 89 deletions(-) diff --git a/gltf/stream.cpp b/gltf/stream.cpp index 1a343f0f52..70c533700d 100644 --- a/gltf/stream.cpp +++ b/gltf/stream.cpp @@ -383,6 +383,43 @@ static StreamFormat writeVertexStreamRaw(std::string& bin, const Stream& stream, return format; } +static StreamFormat writeVertexStreamFloat(std::string& bin, const Stream& stream, cgltf_type type, int components, const Settings& settings, int bits, int min_exp = -100) +{ + assert(components >= 1 && components <= 4); + + StreamFormat::Filter filter = settings.compress ? StreamFormat::Filter_Exp : StreamFormat::Filter_None; + + if (settings.compressmore) + { + encodeExpParallel(bin, &stream.data[0], stream.data.size(), components, bits + 1, min_exp); + } + else + { + for (size_t i = 0; i < stream.data.size(); ++i) + { + const Attr& a = stream.data[i]; + + if (filter == StreamFormat::Filter_Exp) + { + uint32_t v[4]; + for (int k = 0; k < components; ++k) + v[k] = encodeExpOne(a.f[k], bits + 1, min_exp); + bin.append(reinterpret_cast(v), sizeof(uint32_t) * components); + } + else + { + float v[4]; + for (int k = 0; k < components; ++k) + v[k] = meshopt_quantizeFloat(a.f[k], bits); + bin.append(reinterpret_cast(v), sizeof(float) * components); + } + } + } + + StreamFormat format = {type, cgltf_component_type_r_32f, false, sizeof(float) * components, filter}; + return format; +} + static int quantizeColor(float v, int bytebits, int bits) { int result = meshopt_quantizeUnorm(v, bytebits); @@ -401,41 +438,7 @@ StreamFormat writeVertexStream(std::string& bin, const Stream& stream, const Qua return writeVertexStreamRaw(bin, stream, cgltf_type_vec3, 3); if (settings.pos_float) - { - StreamFormat::Filter filter = settings.compress ? StreamFormat::Filter_Exp : StreamFormat::Filter_None; - - if (settings.compressmore) - { - encodeExpParallel(bin, &stream.data[0], stream.data.size(), 3, qp.bits + 1); - } - else - { - for (size_t i = 0; i < stream.data.size(); ++i) - { - const Attr& a = stream.data[i]; - - if (filter == StreamFormat::Filter_Exp) - { - uint32_t v[3]; - v[0] = encodeExpOne(a.f[0], qp.bits + 1); - v[1] = encodeExpOne(a.f[1], qp.bits + 1); - v[2] = encodeExpOne(a.f[2], qp.bits + 1); - bin.append(reinterpret_cast(v), sizeof(v)); - } - else - { - float v[3] = { - meshopt_quantizeFloat(a.f[0], qp.bits), - meshopt_quantizeFloat(a.f[1], qp.bits), - meshopt_quantizeFloat(a.f[2], qp.bits)}; - bin.append(reinterpret_cast(v), sizeof(v)); - } - } - } - - StreamFormat format = {cgltf_type_vec3, cgltf_component_type_r_32f, false, 12, filter}; - return format; - } + return writeVertexStreamFloat(bin, stream, cgltf_type_vec3, 3, settings, qp.bits); if (stream.target == 0) { @@ -512,66 +515,29 @@ StreamFormat writeVertexStream(std::string& bin, const Stream& stream, const Qua if (!settings.quantize) return writeVertexStreamRaw(bin, stream, cgltf_type_vec2, 2); + // expand the encoded range to ensure it covers [0..1) interval + // this can slightly reduce precision but we should not need more precision inside 0..1, and this significantly improves compressed size when using encodeExpOne if (settings.tex_float) - { - StreamFormat::Filter filter = settings.compress ? StreamFormat::Filter_Exp : StreamFormat::Filter_None; + return writeVertexStreamFloat(bin, stream, cgltf_type_vec2, 2, settings, qt.bits, /* min_exp= */ 0); - // expand the encoded range to ensure it covers [0..1) interval - // this can slightly reduce precision but we should not need more precision inside 0..1, and this significantly - // improves compressed size when using encodeExpOne - const int min_exp = 0; + float uv_rscale[2] = { + qt.scale[0] == 0.f ? 0.f : 1.f / qt.scale[0], + qt.scale[1] == 0.f ? 0.f : 1.f / qt.scale[1], + }; - if (settings.compressmore) - { - encodeExpParallel(bin, &stream.data[0], stream.data.size(), 2, qt.bits + 1, min_exp); - } - else - { - for (size_t i = 0; i < stream.data.size(); ++i) - { - const Attr& a = stream.data[i]; - - if (filter == StreamFormat::Filter_Exp) - { - uint32_t v[2]; - v[0] = encodeExpOne(a.f[0], qt.bits + 1, min_exp); - v[1] = encodeExpOne(a.f[1], qt.bits + 1, min_exp); - bin.append(reinterpret_cast(v), sizeof(v)); - } - else - { - float v[2] = { - meshopt_quantizeFloat(a.f[0], qt.bits), - meshopt_quantizeFloat(a.f[1], qt.bits)}; - bin.append(reinterpret_cast(v), sizeof(v)); - } - } - } - - StreamFormat format = {cgltf_type_vec2, cgltf_component_type_r_32f, false, 8, filter}; - return format; - } - else + for (size_t i = 0; i < stream.data.size(); ++i) { - float uv_rscale[2] = { - qt.scale[0] == 0.f ? 0.f : 1.f / qt.scale[0], - qt.scale[1] == 0.f ? 0.f : 1.f / qt.scale[1], - }; - - for (size_t i = 0; i < stream.data.size(); ++i) - { - const Attr& a = stream.data[i]; - - uint16_t v[2] = { - uint16_t(meshopt_quantizeUnorm((a.f[0] - qt.offset[0]) * uv_rscale[0], qt.bits)), - uint16_t(meshopt_quantizeUnorm((a.f[1] - qt.offset[1]) * uv_rscale[1], qt.bits)), - }; - bin.append(reinterpret_cast(v), sizeof(v)); - } + const Attr& a = stream.data[i]; - StreamFormat format = {cgltf_type_vec2, cgltf_component_type_r_16u, qt.normalized, 4}; - return format; + uint16_t v[2] = { + uint16_t(meshopt_quantizeUnorm((a.f[0] - qt.offset[0]) * uv_rscale[0], qt.bits)), + uint16_t(meshopt_quantizeUnorm((a.f[1] - qt.offset[1]) * uv_rscale[1], qt.bits)), + }; + bin.append(reinterpret_cast(v), sizeof(v)); } + + StreamFormat format = {cgltf_type_vec2, cgltf_component_type_r_16u, qt.normalized, 4}; + return format; } else if (stream.type == cgltf_attribute_type_normal) { From 89268f34733eb493939d90b9fa1840ff629c707b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 16 Nov 2023 10:04:03 -0800 Subject: [PATCH 003/581] gltfpack: Remove normal streams from meshes with unlit materials Unlit materials do not require normals or tangents; we already automatically filter out tangents because of the lack of normal texture or other material extensions, but normals were not removed until now. This can reduce the amount of geometry we need to output; this also mostly subsumes the redundant normal stream filtering for point clouds as point clouds often have an unlit material, but for now we'll keep that redundancy. When material variants are used, we only do this when all material variants for a given mesh are unlit. The use of the default material also blocks this optimization as default material implies basic lighting. --- gltf/gltfpack.cpp | 1 + gltf/gltfpack.h | 2 ++ gltf/material.cpp | 3 +++ gltf/mesh.cpp | 3 +++ 4 files changed, 9 insertions(+) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index fabc586d39..3e97d32144 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -354,6 +354,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output mi.needsTangents |= vi.needsTangents; mi.textureSetMask |= vi.textureSetMask; + mi.unlit &= vi.unlit; } filterStreams(mesh, mi); diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index c3257589f4..fed181ea08 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -219,6 +219,8 @@ struct MaterialInfo bool usesTextureTransform; bool needsTangents; + bool unlit; + unsigned int textureSetMask; int remap; diff --git a/gltf/material.cpp b/gltf/material.cpp index 59238ac14a..9b1ad14a3b 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -500,6 +500,9 @@ static void analyzeMaterial(const cgltf_material& material, MaterialInfo& mi, cg analyzeMaterialTexture(material.normal_texture, TextureKind_Normal, mi, data, textures, images); analyzeMaterialTexture(material.occlusion_texture, TextureKind_Attrib, mi, data, textures, images); analyzeMaterialTexture(material.emissive_texture, TextureKind_Color, mi, data, textures, images); + + if (material.unlit) + mi.unlit = true; } void analyzeMaterials(cgltf_data* data, std::vector& materials, std::vector& textures, std::vector& images) diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index 2f4b29fd0d..d99be38eef 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -424,6 +424,9 @@ void filterStreams(Mesh& mesh, const MaterialInfo& mi) if (stream.type == cgltf_attribute_type_texcoord && stream.index > keep_texture_set) continue; + if (stream.type == cgltf_attribute_type_normal && mi.unlit) + continue; + if (stream.type == cgltf_attribute_type_tangent && !mi.needsTangents) continue; From e3aab8bc14ed4a78bdb83303355689a96a31528c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 16 Nov 2023 10:09:15 -0800 Subject: [PATCH 004/581] gltfpack: Introduce optional floating-point normal quantization Usually normalized integer storage is optimal for normals; however, morph target deltas require a [-2, 2] storage range. During quantization we clamp them to [-1, 1] which ends up usually working fine, however there are some use cases where this doesn't work well when the normal deformation is extreme. This can be solved by scaling normals by 0.5, so we'll use [-0.5, 0.5] range for base normal and [-1, 1] range for normal deltas. This usually works fine with any glTF renderers as they normalize the normal (which is more or less required for handling non-uniform scale transforms). However, the validator treats files like this as invalid. Validator doesn't process files with -c/cc so technically we could fix this when compression is enabled, but that would result in an odd mismatch where compression *improves* quality instead of degrading it... For now we introduce an option to use floating point normals, quantized using reduced mantissa and stored, when compression is enabled, using exponential filter. Similarly to -vtf, this isn't normally the recommended mode but there might be cases where it's a desireable tradeoff. --- gltf/gltfpack.cpp | 8 ++++++-- gltf/gltfpack.h | 1 + gltf/stream.cpp | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index fabc586d39..1f544e1d4e 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -1256,6 +1256,10 @@ int main(int argc, char** argv) { settings.tex_float = true; } + else if (strcmp(arg, "-vnf") == 0) + { + settings.nrm_float = true; + } else if (strcmp(arg, "-at") == 0 && i + 1 < argc && isdigit(argv[i + 1][0])) { settings.trn_bits = clamp(atoi(argv[++i]), 1, 24); @@ -1581,9 +1585,9 @@ int main(int argc, char** argv) return 1; } - if (settings.fallback && (settings.pos_float || settings.tex_float)) + if (settings.fallback && (settings.pos_float || settings.tex_float || settings.nrm_float)) { - fprintf(stderr, "Option -cf can not be used together with -vpf or -tpf\n"); + fprintf(stderr, "Option -cf can not be used together with -vpf, -vtf or -vnf\n"); return 1; } diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index c3257589f4..5d0c2a03a0 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -117,6 +117,7 @@ struct Settings bool pos_normalized; bool pos_float; bool tex_float; + bool nrm_float; int trn_bits; int rot_bits; diff --git a/gltf/stream.cpp b/gltf/stream.cpp index 70c533700d..6d8ad2b271 100644 --- a/gltf/stream.cpp +++ b/gltf/stream.cpp @@ -544,6 +544,10 @@ StreamFormat writeVertexStream(std::string& bin, const Stream& stream, const Qua if (!settings.quantize) return writeVertexStreamRaw(bin, stream, cgltf_type_vec3, 3); + // expand the encoded range to ensure it covers [0..1) interval + if (settings.nrm_float) + return writeVertexStreamFloat(bin, stream, cgltf_type_vec3, 3, settings, settings.nrm_bits, /* min_exp= */ 0); + bool oct = settings.compressmore && stream.target == 0; int bits = settings.nrm_bits; From e2ee634bc04af57265d493d92a05cd5e491e31b7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 16 Nov 2023 18:23:54 -0800 Subject: [PATCH 005/581] clang-format Note: this change ignores formatting of ternaries where clang-format makes a very wrong decision, as well as a few small bits that might need code adjustment in the future to avoid misformats. --- gltf/mesh.cpp | 6 +++--- gltf/parsegltf.cpp | 7 +++---- gltf/parseobj.cpp | 2 +- gltf/stream.cpp | 2 +- src/simplifier.cpp | 6 +++--- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index 2f4b29fd0d..7d02cd1bdb 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -405,8 +405,8 @@ void filterStreams(Mesh& mesh, const MaterialInfo& mi) if (stream.target) { - morph_normal = morph_normal || (stream.type == cgltf_attribute_type_normal && !isConstant(stream.data, { 0, 0, 0, 0 })); - morph_tangent = morph_tangent || (stream.type == cgltf_attribute_type_tangent && !isConstant(stream.data, { 0, 0, 0, 0 })); + morph_normal = morph_normal || (stream.type == cgltf_attribute_type_normal && !isConstant(stream.data, {0, 0, 0, 0})); + morph_tangent = morph_tangent || (stream.type == cgltf_attribute_type_tangent && !isConstant(stream.data, {0, 0, 0, 0})); } if (stream.type == cgltf_attribute_type_texcoord && stream.index < 32 && (mi.textureSetMask & (1u << stream.index)) != 0) @@ -430,7 +430,7 @@ void filterStreams(Mesh& mesh, const MaterialInfo& mi) if ((stream.type == cgltf_attribute_type_joints || stream.type == cgltf_attribute_type_weights) && !mesh.skin) continue; - if (stream.type == cgltf_attribute_type_color && isConstant(stream.data, { 1, 1, 1, 1 })) + if (stream.type == cgltf_attribute_type_color && isConstant(stream.data, {1, 1, 1, 1})) continue; if (stream.target && stream.type == cgltf_attribute_type_normal && !morph_normal) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 5bf36b0b20..634d4ba5c6 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -140,10 +140,9 @@ static void fixupIndices(std::vector& indices, cgltf_primitive_typ static bool isIdAttribute(const char* name) { - return - strcmp(name, "_ID") == 0 || - strcmp(name, "_BATCHID") == 0 || - strncmp(name, "_FEATURE_ID_", 12) == 0; + return strcmp(name, "_ID") == 0 || + strcmp(name, "_BATCHID") == 0 || + strncmp(name, "_FEATURE_ID_", 12) == 0; } static void parseMeshesGltf(cgltf_data* data, std::vector& meshes, std::vector >& mesh_remap) diff --git a/gltf/parseobj.cpp b/gltf/parseobj.cpp index ed06b9f0ff..d353d544bb 100644 --- a/gltf/parseobj.cpp +++ b/gltf/parseobj.cpp @@ -235,7 +235,7 @@ static void parseMeshGroupObj(fastObjMesh* obj, const fastObjGroup& og, cgltf_da unsigned int face_vertex_offset = og.index_offset; unsigned int face_end_offset = og.face_offset + og.face_count; - for (unsigned int face_offset = og.face_offset; face_offset < face_end_offset; ) + for (unsigned int face_offset = og.face_offset; face_offset < face_end_offset;) { unsigned int mi = obj->face_materials[face_offset]; diff --git a/gltf/stream.cpp b/gltf/stream.cpp index 70c533700d..295540310a 100644 --- a/gltf/stream.cpp +++ b/gltf/stream.cpp @@ -410,7 +410,7 @@ static StreamFormat writeVertexStreamFloat(std::string& bin, const Stream& strea { float v[4]; for (int k = 0; k < components; ++k) - v[k] = meshopt_quantizeFloat(a.f[k], bits); + v[k] = meshopt_quantizeFloat(a.f[k], bits); bin.append(reinterpret_cast(v), sizeof(float) * components); } } diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 2033d190b8..4073bb4dc7 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -580,7 +580,7 @@ static float quadricError(const Quadric& Q, const QuadricGrad* G, size_t attribu } // TODO: weight normalization is breaking attribute error somehow - float s = 1;// Q.w == 0.f ? 0.f : 1.f / Q.w; + float s = 1; // Q.w == 0.f ? 0.f : 1.f / Q.w; return fabsf(r) * s; } @@ -1325,7 +1325,7 @@ static void fillCellQuadrics(Quadric* cell_quadrics, const unsigned int* indices static void fillCellReservoirs(Reservoir* cell_reservoirs, size_t cell_count, const Vector3* vertex_positions, const float* vertex_colors, size_t vertex_colors_stride, size_t vertex_count, const unsigned int* vertex_cells) { - static const float dummy_color[] = { 0.f, 0.f, 0.f }; + static const float dummy_color[] = {0.f, 0.f, 0.f}; size_t vertex_colors_stride_float = vertex_colors_stride / sizeof(float); @@ -1380,7 +1380,7 @@ static void fillCellRemap(unsigned int* cell_remap, float* cell_errors, size_t c static void fillCellRemap(unsigned int* cell_remap, float* cell_errors, size_t cell_count, const unsigned int* vertex_cells, const Reservoir* cell_reservoirs, const Vector3* vertex_positions, const float* vertex_colors, size_t vertex_colors_stride, float color_weight, size_t vertex_count) { - static const float dummy_color[] = { 0.f, 0.f, 0.f }; + static const float dummy_color[] = {0.f, 0.f, 0.f}; size_t vertex_colors_stride_float = vertex_colors_stride / sizeof(float); From f95a0bb93d9a41d17c6df937a11a85fc340dbdfd Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 17 Nov 2023 07:36:26 -0800 Subject: [PATCH 006/581] gltfpack: Update help to account for vtf/vnf and remove vtn On further reflection, vtn was added prematurely: it only allows setting the texture coordinate compression mode to default which isn't actually useful until we add automatic modes, and once we do a lot of things will change. This was not very obvious when only vpf and vtf existed, but with vnf as well it's definitely not a good idea to also add vnn... Removing this should hopefully be fine since it was a no-op argument that wasn't documented or advertised anywhere but the command line. --- gltf/gltfpack.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index cacc709e4f..633ff958ee 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -1249,10 +1249,6 @@ int main(int argc, char** argv) { settings.pos_float = true; } - else if (strcmp(arg, "-vtn") == 0) - { - settings.tex_float = false; - } else if (strcmp(arg, "-vtf") == 0) { settings.tex_float = true; @@ -1499,7 +1495,7 @@ int main(int argc, char** argv) fprintf(stderr, "\t-si R: simplify meshes targeting triangle/point count ratio R (default: 1; R should be between 0 and 1)\n"); fprintf(stderr, "\t-sa: aggressively simplify to the target ratio disregarding quality\n"); fprintf(stderr, "\t-slb: lock border vertices during simplification to avoid gaps on connected meshes\n"); - fprintf(stderr, "\nVertices:\n"); + fprintf(stderr, "\nVertex precision:\n"); fprintf(stderr, "\t-vp N: use N-bit quantization for positions (default: 14; N should be between 1 and 16)\n"); fprintf(stderr, "\t-vt N: use N-bit quantization for texture coordinates (default: 12; N should be between 1 and 16)\n"); fprintf(stderr, "\t-vn N: use N-bit quantization for normals and tangents (default: 8; N should be between 1 and 16)\n"); @@ -1508,9 +1504,9 @@ int main(int argc, char** argv) fprintf(stderr, "\t-vpi: use integer attributes for positions (default)\n"); fprintf(stderr, "\t-vpn: use normalized attributes for positions\n"); fprintf(stderr, "\t-vpf: use floating point attributes for positions\n"); - fprintf(stderr, "\nTexture coordinates:\n"); - fprintf(stderr, "\t-vtn: use normalized attributes for texture coordinates (default)\n"); + fprintf(stderr, "\nVertex attributes:\n"); fprintf(stderr, "\t-vtf: use floating point attributes for texture coordinates\n"); + fprintf(stderr, "\t-vnf: use floating point attributes for normals\n"); fprintf(stderr, "\nAnimations:\n"); fprintf(stderr, "\t-at N: use N-bit quantization for translations (default: 16; N should be between 1 and 24)\n"); fprintf(stderr, "\t-ar N: use N-bit quantization for rotations (default: 12; N should be between 4 and 16)\n"); From 8c3ae2f2441abcb277ee1a8307014d470ea29265 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 18 Nov 2023 22:31:10 -0800 Subject: [PATCH 007/581] overdraw: Remove redundant v2z/v3z swap v2z/v3z are unused in the rest of the function since we just rely on v1z and depth gradients from here on. We already avoided flipping them, so we also avoid swapping them. This fixes a few clang-tidy warnings. --- src/overdrawanalyzer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/overdrawanalyzer.cpp b/src/overdrawanalyzer.cpp index 8b6f254134..31cf6f146a 100644 --- a/src/overdrawanalyzer.cpp +++ b/src/overdrawanalyzer.cpp @@ -53,11 +53,10 @@ static void rasterize(OverdrawBuffer* buffer, float v1x, float v1y, float v1z, f // flip backfacing triangles to simplify rasterization logic if (sign) { - // flipping v2 & v3 preserves depth gradients since they're based on v1 + // flipping v2 & v3 preserves depth gradients since they're based on v1; only v1z is used below float t; t = v2x, v2x = v3x, v3x = t; t = v2y, v2y = v3y, v3y = t; - t = v2z, v2z = v3z, v3z = t; // flip depth since we rasterize backfacing triangles to second buffer with reverse Z; only v1z is used below v1z = kViewport - v1z; From 11b7fd5a7c912d8dac7ae2a6d4237374c531c0c2 Mon Sep 17 00:00:00 2001 From: ruby Date: Sun, 26 Nov 2023 17:20:14 -0400 Subject: [PATCH 008/581] add options to simplify example minor API change --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f8d233d868..e59d10f1c8 100644 --- a/README.md +++ b/README.md @@ -263,11 +263,12 @@ The first simplification algorithm, `meshopt_simplify`, follows the topology of float threshold = 0.2f; size_t target_index_count = size_t(index_count * threshold); float target_error = 1e-2f; +unsigned int options = 0; //meshopt_SimplifyX flags, 0 is a safe default std::vector lod(index_count); float lod_error = 0.f; lod.resize(meshopt_simplify(&lod[0], indices, index_count, &vertices[0].x, vertex_count, sizeof(Vertex), - target_index_count, target_error, &lod_error)); + target_index_count, target_error, options, &lod_error)); ``` Target error is an approximate measure of the deviation from the original mesh using distance normalized to `[0..1]` range (e.g. `1e-2f` means that simplifier will try to maintain the error to be below 1% of the mesh extents). Note that the simplifier attempts to produce the requested number of indices at minimal error, but because of topological restrictions and error limit it is not guaranteed to reach the target index count and can stop earlier. From 20517152a08c32152e545fe51a7d628a40380c26 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 26 Nov 2023 13:29:33 -0800 Subject: [PATCH 009/581] Update README.md Add a missing space --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e59d10f1c8..fbf576ef6b 100644 --- a/README.md +++ b/README.md @@ -263,7 +263,7 @@ The first simplification algorithm, `meshopt_simplify`, follows the topology of float threshold = 0.2f; size_t target_index_count = size_t(index_count * threshold); float target_error = 1e-2f; -unsigned int options = 0; //meshopt_SimplifyX flags, 0 is a safe default +unsigned int options = 0; // meshopt_SimplifyX flags, 0 is a safe default std::vector lod(index_count); float lod_error = 0.f; From 28bd987efa521b9d7301b91448fd32600067c2e9 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 26 Nov 2023 13:30:42 -0800 Subject: [PATCH 010/581] Update cifuzz.yml There's no need to run fuzzer on .md changes --- .github/workflows/cifuzz.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 3c50a50fb2..a0c57dc86c 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -1,5 +1,10 @@ name: CIFuzz -on: [pull_request] + +on: + pull_request: + paths-ignore: + - '*.md' + jobs: Fuzzing: runs-on: ubuntu-latest From 91433d1157f57542476b82a2896f53efc1dd591b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 30 Nov 2023 16:52:42 -0800 Subject: [PATCH 011/581] extern: Update cgltf to latest This includes recent changes to cgltf that increase robustness when parsing invalid files and a change to cgltf_accessor_unpack_indices that requires an associated parsing change for compatibility. --- extern/cgltf.h | 106 ++++++++++++++++++++++++++++++++++----------- gltf/parsegltf.cpp | 2 +- 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/extern/cgltf.h b/extern/cgltf.h index 7fc5652525..24fb08b06a 100644 --- a/extern/cgltf.h +++ b/extern/cgltf.h @@ -63,9 +63,14 @@ * By passing null for the output pointer, users can find out how many floats are required in the * output buffer. * + * `cgltf_accessor_unpack_indices` reads in the index data from an accessor. Assumes that + * `cgltf_load_buffers` has already been called. By passing null for the output pointer, users can + * find out how many indices are required in the output buffer. Returns 0 if the accessor is + * sparse or if the output component size is less than the accessor's component size. + * * `cgltf_num_components` is a tiny utility that tells you the dimensionality of * a certain accessor type. This can be used before `cgltf_accessor_unpack_floats` to help allocate - * the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for + * the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for * similar purposes. * * `cgltf_accessor_read_float` reads a certain element from a non-sparse accessor and converts it to @@ -75,7 +80,7 @@ * * `cgltf_accessor_read_uint` is similar to its floating-point counterpart, but limited to reading * vector types and does not support matrix types. The passed-in element size is the number of uints - * in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in + * in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in * element_size is too small, or if the accessor is sparse. * * `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t @@ -197,6 +202,7 @@ typedef enum cgltf_type typedef enum cgltf_primitive_type { + cgltf_primitive_type_invalid, cgltf_primitive_type_points, cgltf_primitive_type_lines, cgltf_primitive_type_line_loop, @@ -838,7 +844,7 @@ cgltf_size cgltf_component_size(cgltf_component_type component_type); cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type); cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count); -cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count); +cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count); /* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size); @@ -938,8 +944,8 @@ static int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t #ifndef CGLTF_CONSTS -static const cgltf_size GlbHeaderSize = 12; -static const cgltf_size GlbChunkHeaderSize = 8; +#define GlbHeaderSize 12 +#define GlbChunkHeaderSize 8 static const uint32_t GlbVersion = 2; static const uint32_t GlbMagic = 0x46546C67; static const uint32_t GlbMagicJsonChunk = 0x4E4F534A; @@ -1033,7 +1039,7 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m fclose(file); return cgltf_result_out_of_memory; } - + cgltf_size read_size = fread(file_data, 1, file_size, file); fclose(file); @@ -1634,6 +1640,7 @@ cgltf_result cgltf_validate(cgltf_data* data) for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j) { + CGLTF_ASSERT_IF(data->meshes[i].primitives[j].type == cgltf_primitive_type_invalid, cgltf_result_invalid_gltf); CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf); CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes_count == 0, cgltf_result_invalid_gltf); @@ -1735,6 +1742,11 @@ cgltf_result cgltf_validate(cgltf_data* data) } } + for (cgltf_size i = 0; i < data->variants_count; ++i) + { + CGLTF_ASSERT_IF(!data->variants[i].name, cgltf_result_invalid_gltf); + } + return cgltf_result_success; } @@ -1909,7 +1921,7 @@ void cgltf_free(cgltf_data* data) data->memory.free_func(data->memory.user_data, data->materials); - for (cgltf_size i = 0; i < data->images_count; ++i) + for (cgltf_size i = 0; i < data->images_count; ++i) { data->memory.free_func(data->memory.user_data, data->images[i].name); data->memory.free_func(data->memory.user_data, data->images[i].uri); @@ -2557,7 +2569,7 @@ cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const return (cgltf_size)(object - animation->channels); } -cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count) +cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count) { if (out == NULL) { @@ -2565,6 +2577,7 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u } index_count = accessor->count < index_count ? accessor->count : index_count; + cgltf_size index_component_size = cgltf_component_size(accessor->component_type); if (accessor->is_sparse) { @@ -2574,6 +2587,10 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u { return 0; } + if (index_component_size > out_component_size) + { + return 0; + } const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view); if (element == NULL) { @@ -2581,18 +2598,29 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_u } element += accessor->offset; - if (accessor->component_type == cgltf_component_type_r_32u && accessor->stride == sizeof(cgltf_uint)) + if (index_component_size == out_component_size && accessor->stride == out_component_size) { - memcpy(out, element, index_count * sizeof(cgltf_uint)); + memcpy(out, element, index_count * index_component_size); + return index_count; } - else - { - cgltf_uint* dest = out; - for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride) + // The component size of the output array is larger than the component size of the index data, so index data will be padded. + switch (out_component_size) + { + case 2: + for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride) + { + ((uint16_t*)out)[index] = (uint16_t)cgltf_component_read_index(element, accessor->component_type); + } + break; + case 4: + for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride) { - *dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type); + ((uint32_t*)out)[index] = (uint32_t)cgltf_component_read_index(element, accessor->component_type); } + break; + default: + break; } return index_count; @@ -2818,6 +2846,11 @@ static void cgltf_parse_attribute_type(const char* name, cgltf_attribute_type* o if (us && *out_type != cgltf_attribute_type_invalid) { *out_index = CGLTF_ATOI(us + 1); + if (*out_index < 0) + { + *out_type = cgltf_attribute_type_invalid; + *out_index = 0; + } } } @@ -3150,6 +3183,31 @@ static int cgltf_parse_json_material_mappings(cgltf_options* options, jsmntok_t return i; } +static cgltf_primitive_type cgltf_json_to_primitive_type(jsmntok_t const* tok, const uint8_t* json_chunk) +{ + int type = cgltf_json_to_int(tok, json_chunk); + + switch (type) + { + case 0: + return cgltf_primitive_type_points; + case 1: + return cgltf_primitive_type_lines; + case 2: + return cgltf_primitive_type_line_loop; + case 3: + return cgltf_primitive_type_line_strip; + case 4: + return cgltf_primitive_type_triangles; + case 5: + return cgltf_primitive_type_triangle_strip; + case 6: + return cgltf_primitive_type_triangle_fan; + default: + return cgltf_primitive_type_invalid; + } +} + static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -3166,9 +3224,7 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0) { ++i; - out_prim->type - = (cgltf_primitive_type) - cgltf_json_to_int(tokens+i, json_chunk); + out_prim->type = cgltf_json_to_primitive_type(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0) @@ -3707,7 +3763,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0) { ++i; out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk); @@ -3776,11 +3832,11 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt if (cgltf_json_strcmp(tokens+i, json_chunk, "metallicFactor") == 0) { ++i; - out_pbr->metallic_factor = + out_pbr->metallic_factor = cgltf_json_to_float(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0) + else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0) { ++i; out_pbr->roughness_factor = @@ -4248,11 +4304,11 @@ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* token int size = tokens[i].size; ++i; - for (int j = 0; j < size; ++j) + for (int j = 0; j < size; ++j) { CGLTF_CHECK_KEY(tokens[i]); - if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0) + if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0) { i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri); } @@ -4332,7 +4388,7 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok = cgltf_json_to_int(tokens + i, json_chunk); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0) { ++i; out_sampler->wrap_t @@ -4382,7 +4438,7 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok out_texture->sampler = CGLTF_PTRINDEX(cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk)); ++i; } - else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) { ++i; out_texture->image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk)); diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 634d4ba5c6..9ebb072437 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -188,7 +188,7 @@ static void parseMeshesGltf(cgltf_data* data, std::vector& meshes, std::ve { result.indices.resize(primitive.indices->count); if (!result.indices.empty()) - cgltf_accessor_unpack_indices(primitive.indices, &result.indices[0], result.indices.size()); + cgltf_accessor_unpack_indices(primitive.indices, &result.indices[0], sizeof(unsigned int), result.indices.size()); for (size_t i = 0; i < result.indices.size(); ++i) assert(result.indices[i] < vertex_count); From f7982fca28a8238180a7a6f77fa41cf736054b73 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 3 Dec 2023 08:47:21 -0800 Subject: [PATCH 012/581] extern: Update cgltf to include the GLB parsing fix This is a regression from the recent update so we need to apply the patch from https://github.com/jkuhlmann/cgltf/pull/240 --- extern/cgltf.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extern/cgltf.h b/extern/cgltf.h index 24fb08b06a..76a14665b8 100644 --- a/extern/cgltf.h +++ b/extern/cgltf.h @@ -1147,7 +1147,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s // JSON chunk: length uint32_t json_length; memcpy(&json_length, json_chunk, 4); - if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size) + if (json_length > size - GlbHeaderSize - GlbChunkHeaderSize) { return cgltf_result_data_too_short; } @@ -1164,7 +1164,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s const void* bin = NULL; cgltf_size bin_size = 0; - if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size) + if (GlbChunkHeaderSize <= size - GlbHeaderSize - GlbChunkHeaderSize - json_length) { // We can read another chunk const uint8_t* bin_chunk = json_chunk + json_length; @@ -1172,7 +1172,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s // Bin chunk: length uint32_t bin_length; memcpy(&bin_length, bin_chunk, 4); - if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size) + if (bin_length > size - GlbHeaderSize - GlbChunkHeaderSize - json_length - GlbChunkHeaderSize) { return cgltf_result_data_too_short; } From 2c24381273243de2dee5bc5d76ac18c28af457e6 Mon Sep 17 00:00:00 2001 From: Guilherme Avila <3927951+sciecode@users.noreply.github.com> Date: Thu, 7 Dec 2023 20:23:19 -0300 Subject: [PATCH 013/581] vcacheoptimizer: Remove redundant live_count buffer (#638) live_count can alias adjacency.counts as they always contain the same data; this saves a little bit of memory and time. --- src/vcacheoptimizer.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/vcacheoptimizer.cpp b/src/vcacheoptimizer.cpp index d4b08ba340..5e2504fae5 100644 --- a/src/vcacheoptimizer.cpp +++ b/src/vcacheoptimizer.cpp @@ -196,8 +196,7 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned buildTriangleAdjacency(adjacency, indices, index_count, vertex_count, allocator); // live triangle counts - unsigned int* live_triangles = allocator.allocate(vertex_count); - memcpy(live_triangles, adjacency.counts, vertex_count * sizeof(unsigned int)); + unsigned int* live_triangles = adjacency.counts; // emitted flags unsigned char* emitted_flags = allocator.allocate(face_count); @@ -268,13 +267,9 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned cache = cache_new, cache_new = cache_temp; cache_count = cache_write > cache_size ? cache_size : cache_write; - // update live triangle counts - live_triangles[a]--; - live_triangles[b]--; - live_triangles[c]--; - // remove emitted triangle from adjacency data // this makes sure that we spend less time traversing these lists on subsequent iterations + // live triangle counts are updated as a byproduct of these adjustments for (size_t k = 0; k < 3; ++k) { unsigned int index = indices[current_triangle * 3 + k]; From 440f12c191381f7db0d4c4c6b5535d3a185528b9 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 7 Dec 2023 15:26:56 -0800 Subject: [PATCH 014/581] vcacheoptimizer: Adjust comment to make aliasing more apparent --- src/vcacheoptimizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcacheoptimizer.cpp b/src/vcacheoptimizer.cpp index 5e2504fae5..5cb7743680 100644 --- a/src/vcacheoptimizer.cpp +++ b/src/vcacheoptimizer.cpp @@ -195,7 +195,7 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned TriangleAdjacency adjacency = {}; buildTriangleAdjacency(adjacency, indices, index_count, vertex_count, allocator); - // live triangle counts + // live triangle counts; note, we alias adjacency.counts as we remove triangles after emitting them so the counts always match unsigned int* live_triangles = adjacency.counts; // emitted flags From abb12d3c96e3a3fc7d67d416cf89c49edb988402 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 8 Dec 2023 10:22:33 -0800 Subject: [PATCH 015/581] Update .gitignore to exclude VS CMake intermediate files --- .gitignore | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 56a80c9c79..90b2ac9640 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,12 @@ -/build/ -/data/ -/gltf/library.wasm +# IDE integrations /.idea/ +/.vs/ + +# Build files +/build/ /cmake-build-*/ +/out/ +/gltf/library.wasm + +# Test files +/data/ From e9ed24bd4eb1369c32e3d8da3d870e5a0363e3a7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 8 Dec 2023 10:42:41 -0800 Subject: [PATCH 016/581] vcacheoptimizer: Tweak condition to help MSVC generate branchless code (#639) gcc/clang lower the condition to cmov sequence but MSVC uses branches here; it's important to use branchless lowering as these branches are difficult to predict. This change makes optimizeVertexCache ~7% faster on MSVC on large meshes. --- src/vcacheoptimizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcacheoptimizer.cpp b/src/vcacheoptimizer.cpp index 5cb7743680..e4ecc71d36 100644 --- a/src/vcacheoptimizer.cpp +++ b/src/vcacheoptimizer.cpp @@ -260,7 +260,7 @@ void meshopt_optimizeVertexCacheTable(unsigned int* destination, const unsigned unsigned int index = cache[i]; cache_new[cache_write] = index; - cache_write += (index != a && index != b && index != c); + cache_write += (index != a) & (index != b) & (index != c); } unsigned int* cache_temp = cache; From b9ca3830555cba334879700a9608cf2c3b3d9766 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 10 Dec 2023 22:55:02 -0800 Subject: [PATCH 017/581] quantization: Extract union to a named type This mostly helps clang-format that, in absence of a separate properly formatted declaration, tries to format the union as several lines. --- src/quantization.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/quantization.cpp b/src/quantization.cpp index 09a314d602..149835f501 100644 --- a/src/quantization.cpp +++ b/src/quantization.cpp @@ -3,9 +3,15 @@ #include +union FloatBits +{ + float f; + unsigned int ui; +}; + unsigned short meshopt_quantizeHalf(float v) { - union { float f; unsigned int ui; } u = {v}; + FloatBits u = {v}; unsigned int ui = u.ui; int s = (ui >> 16) & 0x8000; @@ -30,7 +36,7 @@ float meshopt_quantizeFloat(float v, int N) { assert(N >= 0 && N <= 23); - union { float f; unsigned int ui; } u = {v}; + FloatBits u = {v}; unsigned int ui = u.ui; const int mask = (1 << (23 - N)) - 1; @@ -64,7 +70,7 @@ float meshopt_dequantizeHalf(unsigned short h) // 112 is an exponent bias fixup; since we already applied it once, applying it twice converts 31 to 255 r += (em >= (31 << 10)) ? (112 << 23) : 0; - union { float f; unsigned int ui; } u; + FloatBits u; u.ui = s | r; return u.f; } From 95a6336ca67609b823e7ac714d58524a9885b97a Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 10 Dec 2023 22:58:51 -0800 Subject: [PATCH 018/581] Update .gitignore to exclude VS Code files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 90b2ac9640..75ea27b87a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # IDE integrations /.idea/ /.vs/ +/.vscode/ # Build files /build/ From 37c2334c464d28affe032ac193df6e5dfcaf8a25 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 15 Dec 2023 11:26:25 -0800 Subject: [PATCH 019/581] gltfpack: Warn when some materials could not be loaded from the .obj/.mtl This can happen in multiple different ways: - No mtllib reference in the .obj file - mtllib reference in the .obj file that can not be loaded - usemtl references to materials that don't exist in the mtllib --- extern/fast_obj.h | 6 ++++++ gltf/parseobj.cpp | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/extern/fast_obj.h b/extern/fast_obj.h index 0135661197..c57522b314 100644 --- a/extern/fast_obj.h +++ b/extern/fast_obj.h @@ -65,6 +65,9 @@ typedef struct float d; /* Disolve (alpha) */ int illum; /* Illumination model */ + /* Set for materials that don't come from the associated mtllib */ + int fallback; + /* Texture maps */ fastObjTexture map_Ka; fastObjTexture map_Kd; @@ -872,6 +875,8 @@ fastObjMaterial mtl_default(void) mtl.d = 1.0; mtl.illum = 1; + mtl.fallback = 0; + mtl.map_Ka = map_default(); mtl.map_Kd = map_default(); mtl.map_Ks = map_default(); @@ -919,6 +924,7 @@ const char* parse_usemtl(fastObjData* data, const char* ptr) { fastObjMaterial new_mtl = mtl_default(); new_mtl.name = string_copy(s, e); + new_mtl.fallback = 1; array_push(data->mesh->materials, new_mtl); } diff --git a/gltf/parseobj.cpp b/gltf/parseobj.cpp index d353d544bb..7ed713c077 100644 --- a/gltf/parseobj.cpp +++ b/gltf/parseobj.cpp @@ -282,6 +282,13 @@ cgltf_data* parseObj(const char* path, std::vector& meshes, const char** e return NULL; } + int fallback_materials = 0; + for (unsigned int mi = 0; mi < obj->material_count; ++mi) + fallback_materials += obj->materials[mi].fallback; + + if (fallback_materials) + fprintf(stderr, "Warning: %d/%d materials could not be loaded from mtllib\n", fallback_materials, obj->material_count); + cgltf_data* data = (cgltf_data*)calloc(1, sizeof(cgltf_data)); data->memory.free_func = defaultFree; From 1393aa69cdcf02a5f3643204d6f49744bea20389 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 08:40:25 -0800 Subject: [PATCH 020/581] Add macos-14 runner to run CI on M1 --- .github/workflows/build.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9768b2204e..616d29a6f8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -188,3 +188,21 @@ jobs: - uses: actions/checkout@v1 - name: make run: make -j2 config=iphone + + apple: + runs-on: macos-14 + steps: + - uses: actions/checkout@v1 + - name: make test + run: | + make -j2 config=sanitize test + make -j2 config=debug test + make -j2 config=release test + make -j2 config=coverage test + - name: make gltfpack + run: make -j2 config=release gltfpack + - name: upload coverage + run: | + find . -type f -name '*.gcno' -exec gcov -p {} + + sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov + bash <(curl -s https://codecov.io/bash) -f './src*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} From 90d2fe2354516104f24ef5c2eaf498cb4356f005 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 08:58:07 -0800 Subject: [PATCH 021/581] We can now remove the QEMU build ARM NEON implementations should be tested on M1 hardware now. We still need the iphone build for now to test that the code builds for armv7. --- .github/workflows/build.yml | 54 +++++++++++++------------------------ 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 616d29a6f8..44cab11bbd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,6 +33,24 @@ jobs: sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov bash <(curl -s https://codecov.io/bash) -f './src*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} + macos-arm: + runs-on: macos-14 + steps: + - uses: actions/checkout@v1 + - name: make test + run: | + make -j2 config=sanitize test + make -j2 config=debug test + make -j2 config=release test + make -j2 config=coverage test + - name: make gltfpack + run: make -j2 config=release gltfpack + - name: upload coverage + run: | + find . -type f -name '*.gcno' -exec gcov -p {} + + sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov + bash <(curl -s https://codecov.io/bash) -f './src*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} + windows: runs-on: windows-latest strategy: @@ -164,45 +182,9 @@ jobs: sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov bash <(curl -s https://codecov.io/bash) -f './gltf*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} - arm64: - runs-on: ubuntu-latest - steps: - - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset - - uses: docker://multiarch/ubuntu-core:arm64-focal - with: - args: 'uname -a' - - uses: actions/checkout@v1 - - name: make test - uses: docker://multiarch/ubuntu-core:arm64-focal - with: - args: 'bash -c "apt-get update && apt-get install -y build-essential && make -j2 config=coverage test"' - - name: upload coverage - run: | - find . -type f -name '*.gcno' -exec gcov -p {} + - sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov - bash <(curl -s https://codecov.io/bash) -f './src*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} - iphone: runs-on: macos-latest steps: - uses: actions/checkout@v1 - name: make run: make -j2 config=iphone - - apple: - runs-on: macos-14 - steps: - - uses: actions/checkout@v1 - - name: make test - run: | - make -j2 config=sanitize test - make -j2 config=debug test - make -j2 config=release test - make -j2 config=coverage test - - name: make gltfpack - run: make -j2 config=release gltfpack - - name: upload coverage - run: | - find . -type f -name '*.gcno' -exec gcov -p {} + - sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov - bash <(curl -s https://codecov.io/bash) -f './src*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} From c84ddcda4b787ba58e92c605b661b67957791656 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 09:03:31 -0800 Subject: [PATCH 022/581] Use make -j3 for macOS ARM as the runners have 3 vCPUs. --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 44cab11bbd..9ccae05928 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,12 +39,12 @@ jobs: - uses: actions/checkout@v1 - name: make test run: | - make -j2 config=sanitize test - make -j2 config=debug test - make -j2 config=release test - make -j2 config=coverage test + make -j3 config=sanitize test + make -j3 config=debug test + make -j3 config=release test + make -j3 config=coverage test - name: make gltfpack - run: make -j2 config=release gltfpack + run: make -j3 config=release gltfpack - name: upload coverage run: | find . -type f -name '*.gcno' -exec gcov -p {} + From 9a13852db4212cdd21338513804a033ee71c2a51 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 09:09:09 -0800 Subject: [PATCH 023/581] Update copyright year to 2024 ... we have way too many JS files now :-/ --- LICENSE.md | 2 +- gltf/gltfpack.h | 4 ++-- js/meshopt_decoder.js | 2 +- js/meshopt_decoder.module.d.ts | 2 +- js/meshopt_decoder.module.js | 2 +- js/meshopt_decoder_reference.js | 2 +- js/meshopt_encoder.js | 2 +- js/meshopt_encoder.module.d.ts | 2 +- js/meshopt_encoder.module.js | 2 +- js/meshopt_simplifier.js | 2 +- js/meshopt_simplifier.module.d.ts | 2 +- js/meshopt_simplifier.module.js | 2 +- src/meshoptimizer.h | 4 ++-- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 962ed41ffb..ef9f5919f2 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016-2023 Arseny Kapoulkine +Copyright (c) 2016-2024 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index f09a3d53a2..0a2bdf84ea 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -1,7 +1,7 @@ /** * gltfpack - version 0.20 * - * Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at https://github.com/zeux/meshoptimizer * * This application is distributed under the MIT License. See notice at the end of this file. @@ -388,7 +388,7 @@ void writeExtras(std::string& json, const cgltf_extras& extras); void writeScene(std::string& json, const cgltf_scene& scene, const std::string& roots); /** - * Copyright (c) 2016-2023 Arseny Kapoulkine + * Copyright (c) 2016-2024 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/js/meshopt_decoder.js b/js/meshopt_decoder.js index 7062a88f57..1ddd657855 100644 --- a/js/meshopt_decoder.js +++ b/js/meshopt_decoder.js @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptDecoder = (function() { "use strict"; // Built with clang version 16.0.0 diff --git a/js/meshopt_decoder.module.d.ts b/js/meshopt_decoder.module.d.ts index d901928095..8546a2f41a 100644 --- a/js/meshopt_decoder.module.d.ts +++ b/js/meshopt_decoder.module.d.ts @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) export const MeshoptDecoder: { supported: boolean; ready: Promise; diff --git a/js/meshopt_decoder.module.js b/js/meshopt_decoder.module.js index 57f2981702..1936748578 100644 --- a/js/meshopt_decoder.module.js +++ b/js/meshopt_decoder.module.js @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptDecoder = (function() { // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 diff --git a/js/meshopt_decoder_reference.js b/js/meshopt_decoder_reference.js index ab1615620a..cc07de0e1b 100644 --- a/js/meshopt_decoder_reference.js +++ b/js/meshopt_decoder_reference.js @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) // This is the reference decoder implementation by Jasper St. Pierre. // It follows the decoder interface and should be a drop-in replacement for the actual decoder from meshopt_decoder.js diff --git a/js/meshopt_encoder.js b/js/meshopt_encoder.js index 0c9753fcec..e092cb5994 100644 --- a/js/meshopt_encoder.js +++ b/js/meshopt_encoder.js @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptEncoder = (function() { "use strict"; // Built with clang version 16.0.0 diff --git a/js/meshopt_encoder.module.d.ts b/js/meshopt_encoder.module.d.ts index 76e8f2bbe2..4855326aff 100644 --- a/js/meshopt_encoder.module.d.ts +++ b/js/meshopt_encoder.module.d.ts @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) export const MeshoptEncoder: { supported: boolean; ready: Promise; diff --git a/js/meshopt_encoder.module.js b/js/meshopt_encoder.module.js index ada377aaf7..4805e3e7c9 100644 --- a/js/meshopt_encoder.module.js +++ b/js/meshopt_encoder.module.js @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptEncoder = (function() { // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 1acb79e8e4..100bee0d90 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptSimplifier = (function() { "use strict"; // Built with clang version 16.0.0 diff --git a/js/meshopt_simplifier.module.d.ts b/js/meshopt_simplifier.module.d.ts index 9e267e0f97..fe4c0e82b4 100644 --- a/js/meshopt_simplifier.module.d.ts +++ b/js/meshopt_simplifier.module.d.ts @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) export type Flags = "LockBorder"; export const MeshoptSimplifier: { diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index a45ec92c7f..a6c5be8d38 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -1,5 +1,5 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. -// Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +// Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptSimplifier = (function() { // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index dbafd4e6e4..436fc3835f 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -1,7 +1,7 @@ /** * meshoptimizer - version 0.20 * - * Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at https://github.com/zeux/meshoptimizer * * This library is distributed under the MIT License. See notice at the end of this file. @@ -1050,7 +1050,7 @@ inline void meshopt_spatialSortTriangles(T* destination, const T* indices, size_ #endif /** - * Copyright (c) 2016-2023 Arseny Kapoulkine + * Copyright (c) 2016-2024 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation From a4167dcbd3e214b7eeb85950f13a740fdec9dba5 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 09:44:53 -0800 Subject: [PATCH 024/581] Update documentation to mention max_triangles%4==0 max_triangles technically doesn't have to be aligned to a boundary of 4, however because meshlet's triangle data is aligned to 4 bytes for GPU efficiency, if max_triangles is unaligned then it might require overallocating the output triangle buffer for edge cases, which is error prone (and complicates the usage requirements of buildMeshletsBound). This only matters in theory for NVidia that recommends a slightly-not-power-of-two 126 on the higher end to make sure the extra metadata (vertex/triangle count) that is implicitly added to the packet doesn't go over a 128 byte boundary unnecessarily; using 124 in practice is just as good as 126. Fixes #643. --- README.md | 2 +- src/meshoptimizer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fbf576ef6b..28e49393ed 100644 --- a/README.md +++ b/README.md @@ -316,7 +316,7 @@ size_t meshlet_count = meshopt_buildMeshlets(meshlets.data(), meshlet_vertices.d indices.size(), &vertices[0].x, vertices.size(), sizeof(Vertex), max_vertices, max_triangles, cone_weight); ``` -To generate the meshlet data, `max_vertices` and `max_triangles` need to be set within limits supported by the hardware; for NVidia the values of 64 and 124 are recommended. `cone_weight` should be left as 0 if cluster cone culling is not used, and set to a value between 0 and 1 to balance cone culling efficiency with other forms of culling like frustum or occlusion culling. +To generate the meshlet data, `max_vertices` and `max_triangles` need to be set within limits supported by the hardware; for NVidia the values of 64 and 124 are recommended (`max_triangles` must be divisible by 4 so 124 is the value closest to official NVidia's recommended 126). `cone_weight` should be left as 0 if cluster cone culling is not used, and set to a value between 0 and 1 to balance cone culling efficiency with other forms of culling like frustum or occlusion culling. Each resulting meshlet refers to a portion of `meshlet_vertices` and `meshlet_triangles` arrays; this data can be uploaded to GPU and used directly after trimming: diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index 436fc3835f..0619cec8da 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -486,7 +486,7 @@ struct meshopt_Meshlet * meshlet_vertices must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_vertices * meshlet_triangles must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_triangles * 3 * vertex_positions should have float3 position in the first 12 bytes of each vertex - * max_vertices and max_triangles must not exceed implementation limits (max_vertices <= 255 - not 256!, max_triangles <= 512) + * max_vertices and max_triangles must not exceed implementation limits (max_vertices <= 255 - not 256!, max_triangles <= 512; max_triangles must be divisible by 4) * cone_weight should be set to 0 when cone culling is not used, and a value between 0 and 1 otherwise to balance between cluster size and cone culling efficiency */ MESHOPTIMIZER_API size_t meshopt_buildMeshlets(struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t max_vertices, size_t max_triangles, float cone_weight); From 97fffb5db8207816de2d78e71a925859c6f5c50e Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 09:59:04 -0800 Subject: [PATCH 025/581] Add MESHOPT_SOVERSION CMake option to specify soversion This patch is taken from Debian patches: https://salsa.debian.org/roehling/meshoptimizer/-/blob/master/debian/patches/0001-Add-SOVERSION-to-library.patch?ref_type=heads Specifying soversion currently is at the guidance of the packager; experimental APIs are not ABI stable but non-experimental APIs are ABI stable. Since gltfpack uses experimental APIs as well, it probably means that distributions need to bump soversion on library updates in practice. Fixes #644. --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 05171513c0..68aa59f5df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,11 @@ if(MESHOPT_BUILD_SHARED_LIBS) set_target_properties(meshoptimizer PROPERTIES CXX_VISIBILITY_PRESET hidden) set_target_properties(meshoptimizer PROPERTIES VISIBILITY_INLINES_HIDDEN ON) + # soversion may be requested via -DMESHOPT_SOVERSION=n; note that experimental APIs (marked with MESHOPTIMIZER_EXPERIMENTAL) are not ABI-stable + if(MESHOPT_SOVERSION) + set_target_properties(meshoptimizer PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${MESHOPT_SOVERSION}) + endif() + if(WIN32) target_compile_definitions(meshoptimizer INTERFACE "MESHOPTIMIZER_API=__declspec(dllimport)") target_compile_definitions(meshoptimizer PRIVATE "MESHOPTIMIZER_API=__declspec(dllexport)") From 5631b38e8044ebdd1f101f86df590ecafe95bf0d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 17:56:31 -0800 Subject: [PATCH 026/581] Merge macos-arm and unix build definitions We can use (undocumented) support for objects as matrix values to avoid hardcoding -latest suffix --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9ccae05928..485846d25a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,9 +14,9 @@ jobs: unix: strategy: matrix: - os: [ubuntu, macos] - name: ${{matrix.os}} - runs-on: ${{matrix.os}}-latest + os: [{name: ubuntu, version: ubuntu-latest}, {name: macos, version: macos-latest}, {name: macos-arm, version: macos-14}] + name: ${{matrix.os.name}} + runs-on: ${{matrix.os.version}} steps: - uses: actions/checkout@v1 - name: make test From 2cb3c1a7e0231914b36d6ad96177a85c584477e1 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 31 Jan 2024 17:59:26 -0800 Subject: [PATCH 027/581] Remove unnecessary separate definition for macos-arm Note that "unix" job uses -j2 and macos-arm uses -j3 but there does not seem to be any difference right now on this build so it's easy to keep -j2 for the unified configuration. --- .github/workflows/build.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 485846d25a..c388593e80 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,24 +33,6 @@ jobs: sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov bash <(curl -s https://codecov.io/bash) -f './src*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} - macos-arm: - runs-on: macos-14 - steps: - - uses: actions/checkout@v1 - - name: make test - run: | - make -j3 config=sanitize test - make -j3 config=debug test - make -j3 config=release test - make -j3 config=coverage test - - name: make gltfpack - run: make -j3 config=release gltfpack - - name: upload coverage - run: | - find . -type f -name '*.gcno' -exec gcov -p {} + - sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ -\1\2/" *.gcov - bash <(curl -s https://codecov.io/bash) -f './src*.gcov' -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} - windows: runs-on: windows-latest strategy: From fd4c55b13787f6d4be2625e5800a332611769f17 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 9 Feb 2024 11:06:22 -0800 Subject: [PATCH 028/581] Update release.yml Set CMAKE_OSX_ARCHITECTURES to build a fat binary (x86_64 + arm64) for macOS. This makes gltfpack binary runnable without Rosetta and makes it a little faster on Apple Silicon. --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2a24449515..21fd9e26f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: ref: gltfpack path: basis_universal - name: cmake configure - run: cmake . -DMESHOPT_BUILD_GLTFPACK=ON -DMESHOPT_BASISU_PATH=basis_universal -DMESHOPT_WERROR=ON -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -DCMAKE_BUILD_TYPE=Release + run: cmake . -DMESHOPT_BUILD_GLTFPACK=ON -DMESHOPT_BASISU_PATH=basis_universal -DMESHOPT_WERROR=ON -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" - name: cmake build run: cmake --build . --target gltfpack --config Release -j 2 - uses: actions/upload-artifact@v3 From 2e2620c97776d1ea7cfc39b7750775c01e83bff4 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 15 Feb 2024 14:45:25 -0800 Subject: [PATCH 029/581] Update GitHub actions versions to switch to node.js 20 --- .github/workflows/build.yml | 28 ++++++++++++++-------------- .github/workflows/release.yml | 16 ++++++++-------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c388593e80..e1214906d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: name: ${{matrix.os.name}} runs-on: ${{matrix.os.version}} steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: make test run: | make -j2 config=sanitize test @@ -39,7 +39,7 @@ jobs: matrix: arch: [Win32, x64] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: cmake configure run: cmake . -DMESHOPT_BUILD_DEMO=ON -DMESHOPT_BUILD_GLTFPACK=ON -DMESHOPT_WERROR=ON -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$:Debug>" -A ${{matrix.arch}} - name: cmake test @@ -53,8 +53,8 @@ jobs: nodejs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: '16' - name: test decoder @@ -69,8 +69,8 @@ jobs: gltfpack: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: repository: KhronosGroup/glTF-Sample-Assets path: glTF-Sample-Assets @@ -90,8 +90,8 @@ jobs: gltfpack-js: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: '14.x' - name: install wasi @@ -118,8 +118,8 @@ jobs: gltfpack-basis: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: repository: zeux/basis_universal ref: gltfpack @@ -130,13 +130,13 @@ jobs: gltfpack-coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: repository: zeux/basis_universal ref: gltfpack path: basis_universal - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: KhronosGroup/glTF-Sample-Assets path: glTF-Sample-Assets @@ -167,6 +167,6 @@ jobs: iphone: runs-on: macos-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: make run: make -j2 config=iphone diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 21fd9e26f8..045ae1ee70 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,8 +15,8 @@ jobs: name: gltfpack-${{matrix.os}} runs-on: ${{matrix.os}}-latest steps: - - uses: actions/checkout@v1 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: repository: zeux/basis_universal ref: gltfpack @@ -25,12 +25,12 @@ jobs: run: cmake . -DMESHOPT_BUILD_GLTFPACK=ON -DMESHOPT_BASISU_PATH=basis_universal -DMESHOPT_WERROR=ON -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" - name: cmake build run: cmake --build . --target gltfpack --config Release -j 2 - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: gltfpack-windows path: Release/gltfpack.exe if: matrix.os == 'windows' - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: gltfpack-${{matrix.os}} path: gltfpack @@ -39,8 +39,8 @@ jobs: nodejs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: '14.x' - name: install wasi @@ -61,11 +61,11 @@ jobs: cp LICENSE.md js/ cd gltf && npm pack && cd .. cd js && npm pack && cd .. - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: gltfpack-npm path: gltf/gltfpack-*.tgz - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: meshoptimizer-npm path: js/meshoptimizer-*.tgz From 8e87c65bbbc11207194be43a4bb32f39cfd407f5 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 15 Feb 2024 14:50:02 -0800 Subject: [PATCH 030/581] Also switch our own jobs to node 16 Technically node 16 is EOL but we'll keep testing using it to ensure downstream compatibility. --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e1214906d0..08cf4b9d92 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,7 +93,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: '14.x' + node-version: '16' - name: install wasi run: | curl -sL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$VERSION/wasi-sdk-$VERSION.0-linux.tar.gz | tar xz diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 045ae1ee70..fff7e67944 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: '14.x' + node-version: '16' - name: install wasi run: | curl -sL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$VERSION/wasi-sdk-$VERSION.0-linux.tar.gz | tar xz From c9c18d24bb9d665b302b756c42738cc120383976 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 16 Feb 2024 13:09:31 -0800 Subject: [PATCH 031/581] gltfpack: Add support for KHR_materials_dispersion This change adds cgltf parsing support as well as material merging/writing; this extension is similar to KHR_materials_ior in that it's just one extra float. Specification: https://github.com/KhronosGroup/gltf/tree/main/extensions/2.0/Khronos/KHR_materials_dispersion --- extern/cgltf.h | 43 +++++++++++++++++++++++++++++++++++++++++++ gltf/README.md | 1 + gltf/gltfpack.cpp | 3 +++ gltf/material.cpp | 14 ++++++++++++++ gltf/write.cpp | 18 +++++++++++++++++- 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/extern/cgltf.h b/extern/cgltf.h index 76a14665b8..d18230a903 100644 --- a/extern/cgltf.h +++ b/extern/cgltf.h @@ -505,6 +505,11 @@ typedef struct cgltf_anisotropy cgltf_texture_view anisotropy_texture; } cgltf_anisotropy; +typedef struct cgltf_dispersion +{ + cgltf_float dispersion; +} cgltf_dispersion; + typedef struct cgltf_material { char* name; @@ -519,6 +524,7 @@ typedef struct cgltf_material cgltf_bool has_emissive_strength; cgltf_bool has_iridescence; cgltf_bool has_anisotropy; + cgltf_bool has_dispersion; cgltf_pbr_metallic_roughness pbr_metallic_roughness; cgltf_pbr_specular_glossiness pbr_specular_glossiness; cgltf_clearcoat clearcoat; @@ -530,6 +536,7 @@ typedef struct cgltf_material cgltf_emissive_strength emissive_strength; cgltf_iridescence iridescence; cgltf_anisotropy anisotropy; + cgltf_dispersion dispersion; cgltf_texture_view normal_texture; cgltf_texture_view occlusion_texture; cgltf_texture_view emissive_texture; @@ -4297,6 +4304,37 @@ static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* return i; } +static int cgltf_parse_json_dispersion(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_dispersion* out_dispersion) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "dispersion") == 0) + { + ++i; + out_dispersion->dispersion = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else + { + i = cgltf_skip_json(tokens, i + 1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -4690,6 +4728,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to out_material->has_anisotropy = 1; i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_dispersion") == 0) + { + out_material->has_dispersion = 1; + i = cgltf_parse_json_dispersion(tokens, i + 1, json_chunk, &out_material->dispersion); + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); diff --git a/gltf/README.md b/gltf/README.md index 5a115a2781..3319210e00 100644 --- a/gltf/README.md +++ b/gltf/README.md @@ -69,6 +69,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th - KHR_lights_punctual - KHR_materials_anisotropy - KHR_materials_clearcoat +- KHR_materials_dispersion - KHR_materials_emissive_strength - KHR_materials_ior - KHR_materials_iridescence diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 633ff958ee..b20103d3ba 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -439,6 +439,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output bool ext_emissive_strength = false; bool ext_iridescence = false; bool ext_anisotropy = false; + bool ext_dispersion = false; bool ext_unlit = false; bool ext_instancing = false; bool ext_texture_transform = false; @@ -537,6 +538,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output ext_emissive_strength = ext_emissive_strength || material.has_emissive_strength; ext_iridescence = ext_iridescence || material.has_iridescence; ext_anisotropy = ext_anisotropy || material.has_anisotropy; + ext_dispersion = ext_dispersion || material.has_dispersion; ext_unlit = ext_unlit || material.unlit; ext_texture_transform = ext_texture_transform || mi.usesTextureTransform; } @@ -826,6 +828,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output {"KHR_materials_emissive_strength", ext_emissive_strength, false}, {"KHR_materials_iridescence", ext_iridescence, false}, {"KHR_materials_anisotropy", ext_anisotropy, false}, + {"KHR_materials_dispersion", ext_dispersion, false}, {"KHR_materials_unlit", ext_unlit, false}, {"KHR_materials_variants", data->variants_count > 0, false}, {"KHR_lights_punctual", data->lights_count > 0, false}, diff --git a/gltf/material.cpp b/gltf/material.cpp index 9b1ad14a3b..7db0e20f28 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -232,6 +232,14 @@ static bool areMaterialComponentsEqual(const cgltf_anisotropy& lhs, const cgltf_ return true; } +static bool areMaterialComponentsEqual(const cgltf_dispersion& lhs, const cgltf_dispersion& rhs) +{ + if (lhs.dispersion != rhs.dispersion) + return false; + + return true; +} + static bool areMaterialsEqual(const cgltf_material& lhs, const cgltf_material& rhs, const Settings& settings) { if (lhs.has_pbr_metallic_roughness != rhs.has_pbr_metallic_roughness) @@ -300,6 +308,12 @@ static bool areMaterialsEqual(const cgltf_material& lhs, const cgltf_material& r if (lhs.has_anisotropy && !areMaterialComponentsEqual(lhs.anisotropy, rhs.anisotropy)) return false; + if (lhs.has_dispersion != rhs.has_dispersion) + return false; + + if (lhs.has_dispersion && !areMaterialComponentsEqual(lhs.dispersion, rhs.dispersion)) + return false; + if (!areTextureViewsEqual(lhs.normal_texture, rhs.normal_texture)) return false; diff --git a/gltf/write.cpp b/gltf/write.cpp index 5d07bf5e8f..413c96eced 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -580,6 +580,17 @@ static void writeMaterialComponent(std::string& json, const cgltf_data* data, co append(json, "}"); } +static void writeMaterialComponent(std::string& json, const cgltf_data* data, const cgltf_dispersion& tm) +{ + (void)data; + + comma(json); + append(json, "\"KHR_materials_dispersion\":{"); + append(json, "\"dispersion\":"); + append(json, tm.dispersion); + append(json, "}"); +} + void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_material& material, const QuantizationPosition* qp, const QuantizationTexture* qt, std::vector& textures) { if (material.name && *material.name) @@ -649,7 +660,7 @@ void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_materi append(json, "\"doubleSided\":true"); } - if (material.has_pbr_specular_glossiness || material.has_clearcoat || material.has_transmission || material.has_ior || material.has_specular || material.has_sheen || material.has_volume || material.has_emissive_strength || material.has_iridescence || material.has_anisotropy || material.unlit) + if (material.has_pbr_specular_glossiness || material.has_clearcoat || material.has_transmission || material.has_ior || material.has_specular || material.has_sheen || material.has_volume || material.has_emissive_strength || material.has_iridescence || material.has_anisotropy || material.has_dispersion || material.unlit) { comma(json); append(json, "\"extensions\":{"); @@ -704,6 +715,11 @@ void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_materi writeMaterialComponent(json, data, material.anisotropy, qt, textures); } + if (material.has_dispersion) + { + writeMaterialComponent(json, data, material.dispersion); + } + if (material.unlit) { comma(json); From 1b34f94ff4a322ed38673d84c9f76b86524f90b3 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 19 Feb 2024 17:50:46 -0800 Subject: [PATCH 032/581] demo: Switch processDev to meshlets There's some enhancements to stats and/or algorithm that are pending. --- demo/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/demo/main.cpp b/demo/main.cpp index cdfe831ee2..f56660fc16 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -1242,7 +1242,11 @@ void processDev(const char* path) if (!loadMesh(mesh, path)) return; - simplifyAttr(mesh); + Mesh copy = mesh; + meshopt_optimizeVertexCache(©.indices[0], ©.indices[0], copy.indices.size(), copy.vertices.size()); + meshopt_optimizeVertexFetch(©.vertices[0], ©.indices[0], copy.indices.size(), ©.vertices[0], copy.vertices.size(), sizeof(Vertex)); + + meshlets(copy, false); } int main(int argc, char** argv) From 6af78948142fb3243cdaed71f510606317a74f79 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 18 Mar 2024 18:11:29 -0700 Subject: [PATCH 033/581] Update feature_request.md Gently nudge more towards Discussions. --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 83826c668c..910caa9d10 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,6 +1,6 @@ --- name: Feature request -about: Suggest an idea for this project +about: Suggest a feature for this project; please use GitHub Discussions if your idea is not sufficiently concrete title: '' labels: enhancement assignees: '' From b691790ab490da7b19973b1f8606a0d3342148a7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 19 Mar 2024 13:53:44 -0700 Subject: [PATCH 034/581] Work around ASLR+ASAN incompatibility We need to set rnd_bits to 28 for all ASAN executables to run without issues now. --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08cf4b9d92..f537e59d06 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,6 +19,9 @@ jobs: runs-on: ${{matrix.os.version}} steps: - uses: actions/checkout@v4 + - name: work around ASLR+ASAN compatibility + run: sudo sysctl -w vm.mmap_rnd_bits=28 + if: matrix.os.name == 'ubuntu' - name: make test run: | make -j2 config=sanitize test @@ -74,6 +77,8 @@ jobs: with: repository: KhronosGroup/glTF-Sample-Assets path: glTF-Sample-Assets + - name: work around ASLR+ASAN compatibility + run: sudo sysctl -w vm.mmap_rnd_bits=28 - name: make run: make -j2 config=sanitize gltfpack - name: test From bad4d6bd7d9bf604b6df5256f0ec5f0bf27a089f Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 29 Mar 2024 20:46:23 -0700 Subject: [PATCH 035/581] clusterizer: Implement experimental meshlet optimizer So far we were mostly concerned with meshlet clustering from the perspective of treating meshlets as an unordered set of triangles; while this matches the computational and documented model, this may not be optimal for a given GPU. Notably, NVidia GPUs are much more sensitive to the order of triangles in the meshlet than to the number and fill percentage; so much so that from pure rasterization performance, scan may win over proper clustering because it implicitly generates a better order. We do not know the precise criteria / mechanism that NV GPUs use here but it helps to do locality optimization; most importantly, triangle order, but also reordering meshlet-local vertices helps a little bit. This change implements a simple meshlet optimizer; while this can also be achieved by running existing optimization algorithms (vcache / vfetch) on meshlet data, a custom optimizer is faster even when using unoptimized quadratic implementation, and may allow us to implement better locality reodering algorithms in the future assuming a small input patch. For now we just select the next triangle to maximize the number of shared vertices with the previous triangle; this results in a pseudo-strip order which seems reasonably optimal for NV; note that neither the hardware nor this algorithm is concerned with the specifics of edge matching as it doesn't seem to matter for performance. --- src/clusterizer.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++ src/meshoptimizer.h | 10 ++++++ 2 files changed, 88 insertions(+) diff --git a/src/clusterizer.cpp b/src/clusterizer.cpp index c4672ad606..555cd10866 100644 --- a/src/clusterizer.cpp +++ b/src/clusterizer.cpp @@ -882,3 +882,81 @@ meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices return meshopt_computeClusterBounds(indices, triangle_count * 3, vertex_positions, vertex_count, vertex_positions_stride); } + +void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, size_t triangle_count, size_t vertex_count) +{ + using namespace meshopt; + + assert(triangle_count <= kMeshletMaxTriangles); + assert(vertex_count <= kMeshletMaxVertices); + + unsigned char* indices = meshlet_triangles; + unsigned int* vertices = meshlet_vertices; + + unsigned char result[kMeshletMaxTriangles * 3]; + + unsigned char visited[kMeshletMaxTriangles]; + memset(visited, 0, triangle_count); + + unsigned char lasta = 0, lastb = 0, lastc = 0; + + for (size_t i = 0; i < triangle_count; ++i) + { + int next = -1; + + for (int pass = 2; pass >= 0; pass--) + { + for (size_t j = 0; j < triangle_count; ++j) + { + if (visited[j]) + continue; + + unsigned char a = indices[j * 3 + 0], b = indices[j * 3 + 1], c = indices[j * 3 + 2]; + + int aok = (a == lasta || a == lastb || a == lastc); + int bok = (b == lasta || b == lastb || b == lastc); + int cok = (c == lasta || c == lastb || c == lastc); + + if (aok + bok + cok >= pass) + { + next = (int)j; + break; + } + } + + if (next >= 0) + break; + } + + assert(next >= 0); + visited[next] = 1; + result[i * 3 + 0] = lasta = indices[next * 3 + 0]; + result[i * 3 + 1] = lastb = indices[next * 3 + 1]; + result[i * 3 + 2] = lastc = indices[next * 3 + 2]; + } + + memcpy(indices, result, triangle_count * 3); + + unsigned int newv[kMeshletMaxVertices]; + + unsigned char remap[kMeshletMaxVertices]; + memset(remap, -1, vertex_count); + + size_t vertex_offset = 0; + + for (size_t i = 0; i < triangle_count * 3; ++i) + { + unsigned char& r = remap[indices[i]]; + + if (r == 0xff) + { + r = unsigned(vertex_offset); + newv[vertex_offset] = vertices[indices[i]]; + vertex_offset++; + } + + indices[i] = r; + } + + memcpy(vertices, newv, vertex_offset * sizeof(unsigned int)); +} diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index 0619cec8da..6ab48c1968 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -493,6 +493,16 @@ MESHOPTIMIZER_API size_t meshopt_buildMeshlets(struct meshopt_Meshlet* meshlets, MESHOPTIMIZER_API size_t meshopt_buildMeshletsScan(struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles); MESHOPTIMIZER_API size_t meshopt_buildMeshletsBound(size_t index_count, size_t max_vertices, size_t max_triangles); +/** + * Experimental: Meshlet optimizer + * Reorders meshlet vertices and triangles to maximize locality to improve rasterizer throughput + * + * meshlet_triangles and meshlet_vertices must refer to meshlet triangle and vertex index data; when buildMeshlets* is used, these + * need to be computed from meshlet's vertex_offset and triangle_offset + * triangle_count and vertex_count must not exceed implementation limits (vertex_count <= 255 - not 256!, triangle_count <= 512) + */ +MESHOPTIMIZER_EXPERIMENTAL void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, size_t triangle_count, size_t vertex_count); + struct meshopt_Bounds { /* bounding sphere, useful for frustum and occlusion culling */ From b38693e3d1a8f0fa2500a6bed8d1d539574d10ff Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 29 Mar 2024 20:54:29 -0700 Subject: [PATCH 036/581] clusterizer: Use a single pass for meshlet optimization Instead of looking for a triangle with 2 matches and falling back to 1 and 0, unify this and pick the triangle with maximum number of shared vertices, and early out if we found the best possible match. --- src/clusterizer.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/clusterizer.cpp b/src/clusterizer.cpp index 555cd10866..f47d4442a8 100644 --- a/src/clusterizer.cpp +++ b/src/clusterizer.cpp @@ -903,29 +903,27 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh for (size_t i = 0; i < triangle_count; ++i) { int next = -1; + int next_match = -1; - for (int pass = 2; pass >= 0; pass--) + for (size_t j = 0; j < triangle_count; ++j) { - for (size_t j = 0; j < triangle_count; ++j) - { - if (visited[j]) - continue; + if (visited[j]) + continue; - unsigned char a = indices[j * 3 + 0], b = indices[j * 3 + 1], c = indices[j * 3 + 2]; + unsigned char a = indices[j * 3 + 0], b = indices[j * 3 + 1], c = indices[j * 3 + 2]; - int aok = (a == lasta || a == lastb || a == lastc); - int bok = (b == lasta || b == lastb || b == lastc); - int cok = (c == lasta || c == lastb || c == lastc); + int aok = (a == lasta || a == lastb || a == lastc); + int bok = (b == lasta || b == lastb || b == lastc); + int cok = (c == lasta || c == lastb || c == lastc); - if (aok + bok + cok >= pass) - { - next = (int)j; + if (aok + bok + cok > next_match) + { + next = (int)j; + next_match = aok + bok + cok; + + if (next_match == 2) break; - } } - - if (next >= 0) - break; } assert(next >= 0); From 02c0a0513590293ac03c8b3cfe563e46d028089e Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 29 Mar 2024 21:37:02 -0700 Subject: [PATCH 037/581] clusterizer: Switch to a small cache for optimizeMeshlet Instead of only matching against the last triangle, match all previous triangles by tracking the delta between a given cache position; the delta is computed using 8-bit unsigned math so that overflows don't matter as much (there's still a collision between triangles 0 and 256 in the cache but that shouldn't affect the quality noticeably). Experimentally, a cutoff of 3 or 4 produce the same results on NVidia so use 3 for more conservative matching. --- src/clusterizer.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/clusterizer.cpp b/src/clusterizer.cpp index f47d4442a8..b8ce768f4e 100644 --- a/src/clusterizer.cpp +++ b/src/clusterizer.cpp @@ -898,7 +898,11 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh unsigned char visited[kMeshletMaxTriangles]; memset(visited, 0, triangle_count); - unsigned char lasta = 0, lastb = 0, lastc = 0; + unsigned char cache[kMeshletMaxVertices]; + memset(cache, 0, vertex_count); + + unsigned char cache_last = 128; + const unsigned char cache_cutoff = 3; for (size_t i = 0; i < triangle_count; ++i) { @@ -911,26 +915,35 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh continue; unsigned char a = indices[j * 3 + 0], b = indices[j * 3 + 1], c = indices[j * 3 + 2]; + assert(a < vertex_count && b < vertex_count && c < vertex_count); - int aok = (a == lasta || a == lastb || a == lastc); - int bok = (b == lasta || b == lastb || b == lastc); - int cok = (c == lasta || c == lastb || c == lastc); + int aok = (unsigned char)(cache_last - cache[a]) < cache_cutoff; + int bok = (unsigned char)(cache_last - cache[b]) < cache_cutoff; + int cok = (unsigned char)(cache_last - cache[c]) < cache_cutoff; if (aok + bok + cok > next_match) { next = (int)j; next_match = aok + bok + cok; - if (next_match == 2) + if (next_match >= 2) break; } } assert(next >= 0); visited[next] = 1; - result[i * 3 + 0] = lasta = indices[next * 3 + 0]; - result[i * 3 + 1] = lastb = indices[next * 3 + 1]; - result[i * 3 + 2] = lastc = indices[next * 3 + 2]; + + unsigned char a = indices[next * 3 + 0], b = indices[next * 3 + 1], c = indices[next * 3 + 2]; + + result[i * 3 + 0] = a; + result[i * 3 + 1] = b; + result[i * 3 + 2] = c; + + cache_last++; + cache[a] = cache_last; + cache[b] = cache_last; + cache[c] = cache_last; } memcpy(indices, result, triangle_count * 3); From 5b3456da538af88657316c5a7b291577c87f66fb Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 30 Mar 2024 08:50:27 -0700 Subject: [PATCH 038/581] clusterizer: Fix MSVC warning --- src/clusterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clusterizer.cpp b/src/clusterizer.cpp index b8ce768f4e..595dca30ae 100644 --- a/src/clusterizer.cpp +++ b/src/clusterizer.cpp @@ -961,7 +961,7 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh if (r == 0xff) { - r = unsigned(vertex_offset); + r = (unsigned char)(vertex_offset); newv[vertex_offset] = vertices[indices[i]]; vertex_offset++; } From a12987e898af9e806563f6856ac29ef26a32c9ad Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 30 Mar 2024 19:07:20 -0700 Subject: [PATCH 039/581] demo: Add usage examples for meshopt_optimizeMeshlet Mention this in README as a recommended post-processing step and add to meshlet processing pipeline for coverage. --- README.md | 6 ++++++ demo/main.cpp | 3 +++ 2 files changed, 9 insertions(+) diff --git a/README.md b/README.md index 28e49393ed..c42f7c18ff 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,12 @@ meshlets.resize(meshlet_count); However depending on the application other strategies of storing the data can be useful; for example, `meshlet_vertices` serves as indices into the original vertex buffer but it might be worthwhile to generate a mini vertex buffer for each meshlet to remove the extra indirection when accessing vertex data, or it might be desirable to compress vertex data as vertices in each meshlet are likely to be very spatially coherent. +For optimal performance, it is recommended to further optimize each meshlet in isolation for better triangle and vertex locality by calling `meshopt_optimizeMeshlet` on vertex and index data like so: + +```c++ +meshopt_optimizeMeshlet(&meshlet_vertices[m.vertex_offset], &meshlet_triangles[m.triangle_offset], m.triangle_count, m.vertex_count); +``` + After generating the meshlet data, it's also possible to generate extra data for each meshlet that can be saved and used at runtime to perform cluster culling, where each meshlet can be discarded if it's guaranteed to be invisible. To generate the data, `meshlet_computeMeshletBounds` can be used: ```c++ diff --git a/demo/main.cpp b/demo/main.cpp index f56660fc16..457865e021 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -866,6 +866,9 @@ void meshlets(const Mesh& mesh, bool scan) else meshlets.resize(meshopt_buildMeshlets(&meshlets[0], &meshlet_vertices[0], &meshlet_triangles[0], &mesh.indices[0], mesh.indices.size(), &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), max_vertices, max_triangles, cone_weight)); + for (size_t i = 0; i < meshlets.size(); ++i) + meshopt_optimizeMeshlet(&meshlet_vertices[meshlets[i].vertex_offset], &meshlet_triangles[meshlets[i].triangle_offset], meshlets[i].triangle_count, meshlets[i].vertex_count); + if (meshlets.size()) { const meshopt_Meshlet& last = meshlets.back(); From 49e18b0151a907cde6f9550001131b5ee38c772d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 30 Mar 2024 19:54:56 -0700 Subject: [PATCH 040/581] clusterizer: Optimize triangle reordering Instead of tracking visited triangles, maintain an invariant where an increasing prefix of the triangle array is ordered properly. While it would be possible to maintain this by swapping the first triangle with the one we picked at every iteration, this distorts the selection order in an odd way that may reduce the quality of the generated sequence, and memmove is fairly fast in practice given that we've already scanned over the region we are about to move anyhow. This makes optimization ~40% faster while producing the same results. --- src/clusterizer.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/clusterizer.cpp b/src/clusterizer.cpp index 595dca30ae..4c0c6f2e9d 100644 --- a/src/clusterizer.cpp +++ b/src/clusterizer.cpp @@ -893,11 +893,6 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh unsigned char* indices = meshlet_triangles; unsigned int* vertices = meshlet_vertices; - unsigned char result[kMeshletMaxTriangles * 3]; - - unsigned char visited[kMeshletMaxTriangles]; - memset(visited, 0, triangle_count); - unsigned char cache[kMeshletMaxVertices]; memset(cache, 0, vertex_count); @@ -909,11 +904,8 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh int next = -1; int next_match = -1; - for (size_t j = 0; j < triangle_count; ++j) + for (size_t j = i; j < triangle_count; ++j) { - if (visited[j]) - continue; - unsigned char a = indices[j * 3 + 0], b = indices[j * 3 + 1], c = indices[j * 3 + 2]; assert(a < vertex_count && b < vertex_count && c < vertex_count); @@ -932,13 +924,14 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh } assert(next >= 0); - visited[next] = 1; unsigned char a = indices[next * 3 + 0], b = indices[next * 3 + 1], c = indices[next * 3 + 2]; - result[i * 3 + 0] = a; - result[i * 3 + 1] = b; - result[i * 3 + 2] = c; + memmove(indices + (i + 1) * 3, indices + i * 3, (next - i) * 3 * sizeof(unsigned char)); + + indices[i * 3 + 0] = a; + indices[i * 3 + 1] = b; + indices[i * 3 + 2] = c; cache_last++; cache[a] = cache_last; @@ -946,8 +939,6 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh cache[c] = cache_last; } - memcpy(indices, result, triangle_count * 3); - unsigned int newv[kMeshletMaxVertices]; unsigned char remap[kMeshletMaxVertices]; From 8332f4d5c89675fec65802a65423e2773b81d6d8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 30 Mar 2024 20:05:45 -0700 Subject: [PATCH 041/581] clusterizer: Add comments to meshopt_optimizeMeshlet Most of the code is fairly straightforward but some decisions may not be obvious so let's document them. Also renames newv[] to order[] for cleanliness. --- src/clusterizer.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/clusterizer.cpp b/src/clusterizer.cpp index 4c0c6f2e9d..be8c2c2db1 100644 --- a/src/clusterizer.cpp +++ b/src/clusterizer.cpp @@ -893,11 +893,13 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh unsigned char* indices = meshlet_triangles; unsigned int* vertices = meshlet_vertices; + // cache tracks vertex timestamps (corresponding to triangle index! all 3 vertices are added at the same time and never removed) unsigned char cache[kMeshletMaxVertices]; memset(cache, 0, vertex_count); + // note that we start from a value that means all vertices aren't in cache unsigned char cache_last = 128; - const unsigned char cache_cutoff = 3; + const unsigned char cache_cutoff = 3; // 3 triangles = ~5..9 vertices depending on reuse for (size_t i = 0; i < triangle_count; ++i) { @@ -909,6 +911,8 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh unsigned char a = indices[j * 3 + 0], b = indices[j * 3 + 1], c = indices[j * 3 + 2]; assert(a < vertex_count && b < vertex_count && c < vertex_count); + // score each triangle by how many vertices are in cache + // note: the distance is computed using unsigned 8-bit values, so cache timestamp overflow is handled gracefully int aok = (unsigned char)(cache_last - cache[a]) < cache_cutoff; int bok = (unsigned char)(cache_last - cache[b]) < cache_cutoff; int cok = (unsigned char)(cache_last - cache[c]) < cache_cutoff; @@ -918,6 +922,7 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh next = (int)j; next_match = aok + bok + cok; + // note that we could end up with all 3 vertices in the cache, but 2 is enough for ~strip traversal if (next_match >= 2) break; } @@ -927,19 +932,23 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh unsigned char a = indices[next * 3 + 0], b = indices[next * 3 + 1], c = indices[next * 3 + 2]; + // shift triangles before the next one forward so that we always keep an ordered partition + // note: this could have swapped triangles [i] and [next] but that distorts the order and may skew the output sequence memmove(indices + (i + 1) * 3, indices + i * 3, (next - i) * 3 * sizeof(unsigned char)); indices[i * 3 + 0] = a; indices[i * 3 + 1] = b; indices[i * 3 + 2] = c; + // cache timestamp is the same between all vertices of each triangle to reduce overflow cache_last++; cache[a] = cache_last; cache[b] = cache_last; cache[c] = cache_last; } - unsigned int newv[kMeshletMaxVertices]; + // reorder meshlet vertices for access locality assuming index buffer is scanned sequentially + unsigned int order[kMeshletMaxVertices]; unsigned char remap[kMeshletMaxVertices]; memset(remap, -1, vertex_count); @@ -953,12 +962,13 @@ void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* mesh if (r == 0xff) { r = (unsigned char)(vertex_offset); - newv[vertex_offset] = vertices[indices[i]]; + order[vertex_offset] = vertices[indices[i]]; vertex_offset++; } indices[i] = r; } - memcpy(vertices, newv, vertex_offset * sizeof(unsigned int)); + assert(vertex_offset <= vertex_count); + memcpy(vertices, order, vertex_offset * sizeof(unsigned int)); } From 7fe52743723e9315fdc86ca5050101b63b71e14b Mon Sep 17 00:00:00 2001 From: Sylvester Hesp Date: Wed, 3 Apr 2024 01:26:29 +0200 Subject: [PATCH 042/581] Add API to specify which vertices to lock when simplifying (#601) meshopt_simplifyWithAttributes now takes an optional unsigned char* array that allows to specify a locked flag per vertex. --- demo/main.cpp | 2 +- demo/simplify.html | 2 +- demo/tests.cpp | 2 +- js/meshopt_simplifier.js | 39 ++++++++++++++++++------------- js/meshopt_simplifier.module.d.ts | 6 ++--- js/meshopt_simplifier.module.js | 37 +++++++++++++++++------------ js/meshopt_simplifier.test.js | 2 +- src/meshoptimizer.h | 9 +++---- src/simplifier.cpp | 19 +++++++++------ 9 files changed, 69 insertions(+), 49 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index 457865e021..aeb8256994 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -478,7 +478,7 @@ void simplifyAttr(const Mesh& mesh, float threshold = 0.2f) const float attr_weights[3] = {nrm_weight, nrm_weight, nrm_weight}; lod.indices.resize(mesh.indices.size()); // note: simplify needs space for index_count elements in the destination array, not target_index_count - lod.indices.resize(meshopt_simplifyWithAttributes(&lod.indices[0], &mesh.indices[0], mesh.indices.size(), &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), &mesh.vertices[0].nx, sizeof(Vertex), attr_weights, 3, target_index_count, target_error, 0, &result_error)); + lod.indices.resize(meshopt_simplifyWithAttributes(&lod.indices[0], &mesh.indices[0], mesh.indices.size(), &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), &mesh.vertices[0].nx, sizeof(Vertex), attr_weights, 3, NULL, target_index_count, target_error, 0, &result_error)); lod.vertices.resize(lod.indices.size() < mesh.vertices.size() ? lod.indices.size() : mesh.vertices.size()); // note: this is just to reduce the cost of resize() lod.vertices.resize(meshopt_optimizeVertexFetch(&lod.vertices[0], &lod.indices[0], lod.indices.size(), &mesh.vertices[0], mesh.vertices.size(), sizeof(Vertex))); diff --git a/demo/simplify.html b/demo/simplify.html index 8f6c9df199..d4b9534470 100644 --- a/demo/simplify.html +++ b/demo/simplify.html @@ -152,7 +152,7 @@ var res = settings.useAttributes - ? MeshoptSimplifier.simplifyWithAttributes(indices, positions, stride, attrib, attributes, attrib_weights, target, threshold, flags) + ? MeshoptSimplifier.simplifyWithAttributes(indices, positions, stride, attrib, attributes, attrib_weights, null, target, threshold, flags) : MeshoptSimplifier.simplify(indices, positions, stride, target, threshold, flags); console.timeEnd('simplify'); diff --git a/demo/tests.cpp b/demo/tests.cpp index e22851eaec..5eb3d6f2b5 100644 --- a/demo/tests.cpp +++ b/demo/tests.cpp @@ -1181,7 +1181,7 @@ static void simplifyAttr() {12, 14, 21, 21, 14, 23}, }; - assert(meshopt_simplifyWithAttributes(ib[0], ib[0], 7 * 2 * 6, vb[0], 8 * 3, 6 * sizeof(float), vb[0] + 3, 6 * sizeof(float), attr_weights, 3, 6 * 3, 1e-2f) == 18); + assert(meshopt_simplifyWithAttributes(ib[0], ib[0], 7 * 2 * 6, vb[0], 8 * 3, 6 * sizeof(float), vb[0] + 3, 6 * sizeof(float), attr_weights, 3, NULL, 6 * 3, 1e-2f) == 18); assert(memcmp(ib, expected, sizeof(expected)) == 0); } diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 100bee0d90..123fcf4bdb 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -1,12 +1,12 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -var MeshoptSimplifier = (function() { +var MeshoptSimplifier = (function () { "use strict"; // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 - var wasm = "b9H79Tebbbe9Ek9Geueu9Geub9Gbb9GPuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq::9Usdbk;i6iKuY99Ou8Jjjjjbc;W;ab9RgP8KjjjjbaPcwfcbc;Kbz:ljjjb8AaPcualcefgscdtascFFFFi0Ecbyd1:jjjbHjjjjbbgzBdwaPceBd9OaPazBdbaPcuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgHBdxaPcdBd9OaPaHBdlaPaeadalcbz:cjjjbaPcualcdtgOalcFFFFi0EgAcbyd1:jjjbHjjjjbbgCBdzaPciBd9OaPaAcbyd1:jjjbHjjjjbbgXBdCaPclBd9Oalcd4alfhQcehLinaLgscethLasaQ6mbkcbhKaPcuascdtgLascFFFFi0Ecbyd1:jjjbHjjjjbbgQBdKaPcvBd9OaQcFeaLz:ljjjbhYdnalTmbavcd4h8AascufhEinaiaKa8A2cdtfg3ydlgscH4as7c:F:b:DD2a3ydbgscH4as7c;D;O:B8J27a3ydwgscH4as7c:3F;N8N27hQcbhsdndninaYaQaEGgQcdtfg5ydbgLcuSmeaiaLa8A2cdtfa3cxz:ojjjbTmdascefgsaQfhQasaE9nmbxdkka5aKBdbaKhLkaCaKcdtfaLBdbaKcefgKal9hmbkcbhsaXhLinaLasBdbaLclfhLalascefgs9hmbkcbhsaChLaXhQindnasaLydbgESmbaQaXaEcdtfgEydbBdbaEasBdbkaLclfhLaQclfhQalascefgs9hmbkkcbh8EaYcbyd:m:jjjbH:bjjjbbaPclBd9OaPalcbyd1:jjjbHjjjjbbgEBdKaPcvBd9OaPaAcbyd1:jjjbHjjjjbbgsBd3aPcoBd9OaPaAcbyd1:jjjbHjjjjbbgLBdaaPcrBd9OascFeaOz:ljjjbh8FaLcFeaOz:ljjjbhadnalTmbaHcwfhhindnaza8EgQcefg8Ecdtfydbg3azaQcdtgsfydbgLSmba3aL9RhOaHaLcitfhgaaasfh8Ja8FasfhKcbh8Aindndnaga8Acitfydbg5aQ9hmbaKaQBdba8JaQBdbxekdnaza5cdtg8KfgsclfydbgLasydbgsSmbaHascitg3fydbaQSmeaLas9Rh8Lascu7aLfhYaha3fhLcbhsinaYasSmeascefhsaLydbh3aLcwfhLa3aQ9hmbkasa8L6mekaaa8KfgsaQa5asydbcuSEBdbaKa5aQaKydbcuSEBdbka8Acefg8AaO9hmbkka8Eal9hmbkaChLaXhQaah3a8Fh8AcbhsindndnasaLydbg59hmbdnasaQydbg59hmba8Aydbh5dna3ydbgYcu9hmba5cu9hmbaEasfcb86bbxikaEasfhKdnasaYSmbasa5SmbaKce86bbxikaKcl86bbxdkdnasaXa5cdtgYfydb9hmbdna3ydbgKcuSmbasaKSmba8AydbgOcuSmbasaOSmbaaaYfydbggcuSmbaga5Smba8FaYfydbgYcuSmbaYa5SmbdnaCaKcdtfydbaCaYcdtfydb9hmbaCaOcdtfydbaCagcdtfydb9hmbaEasfcd86bbxlkaEasfcl86bbxikaEasfcl86bbxdkaEasfcl86bbxekaEasfaEa5fRbb86bbkaLclfhLaQclfhQa3clfh3a8Aclfh8Aalascefgs9hmbkaxceGTmbaEhsalhLindnasRbbce9hmbascl86bbkascefhsaLcufgLmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8JaPcwfaPyd9Ogscdtfa8JBdbaPascefgOBd9Oa8Jaialavz:djjjbdndnaDmbcbhvxekcbh5aPcwfaOcdtfcuaDal2gLcdtaLcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbaPascdfgOBd9OalTmbarcd4cdthYaDcdthKavh8AinaohsawhLa8AhQaDh3inaQasIdbaLIdbNUdbasclfhsaLclfhLaQclfhQa3cufg3mbkaoaYfhoa8AaKfh8Aa5cefg5al9hmbkkaPcwfaOcdtfcualc8S2gsalc;D;O;f8U0EgQcbyd1:jjjbHjjjjbbgLBdbaPaOcefg3Bd9OaLcbasz:ljjjbh8EdndndnaDTmbaPcwfa3cdtfaQcbyd1:jjjbHjjjjbbgoBdbaPaOcdfgLBd9Oaocbasz:ljjjb8AaPcwfaLcdtfcuaDal2gscltgLascFFFFb0Ecbyd1:jjjbHjjjjbbgwBdbaPaOcifBd9OawcbaLz:ljjjb8AadmexdkcbhocbhwadTmekcbh8AaehLindna8JaLclfydbg5cx2fgsIdba8JaLydbgYcx2fgQIdbg8M:tg8Na8JaLcwfydbgKcx2fg3IdlaQIdlgy:tg8PNa3Idba8M:tgIasIdlay:tg8RN:tg8Sa8SNa8Ra3IdwaQIdwgR:tg8UNa8PasIdwaR:tg8RN:tg8Pa8PNa8RaINa8Ua8NN:tg8Na8NNMM:rgIJbbbb9ETmba8SaI:vh8Sa8NaI:vh8Na8PaI:vh8Pka8EaCaYcdtfydbc8S2fgsa8PaI:rgIa8PNNg8RasIdbMUdbasa8NaIa8NNg8VNg8UasIdlMUdlasa8SaIa8SNg8WNg8XasIdwMUdwasa8Va8PNg8VasIdxMUdxasa8Wa8PNg8YasIdzMUdzasa8Wa8NNg8WasIdCMUdCasa8PaIa8SaRNa8Pa8MNaya8NNMM:mgyNg8MNg8PasIdKMUdKasa8Na8MNg8NasId3MUd3asa8Sa8MNg8SasIdaMUdaasa8MayNg8MasId8KMUd8KasaIasIdyMUdya8EaCa5cdtfydbc8S2fgsa8RasIdbMUdbasa8UasIdlMUdlasa8XasIdwMUdwasa8VasIdxMUdxasa8YasIdzMUdzasa8WasIdCMUdCasa8PasIdKMUdKasa8NasId3MUd3asa8SasIdaMUdaasa8MasId8KMUd8KasaIasIdyMUdya8EaCaKcdtfydbc8S2fgsa8RasIdbMUdbasa8UasIdlMUdlasa8XasIdwMUdwasa8VasIdxMUdxasa8YasIdzMUdzasa8WasIdCMUdCasa8PasIdKMUdKasa8NasId3MUd3asa8SasIdaMUdaasa8MasId8KMUd8KasaIasIdyMUdyaLcxfhLa8Acifg8Aad6mbkcbh5aehYincbhLinaEaeaLc:G1jjbfydba5fcdtfydbgQfRbbhsdndnaEaYaLfydbg3fRbbg8Ac99fcFeGcpe0mbasceSmbascd9hmekdna8AcufcFeGce0mba8Fa3cdtfydbaQ9hmekdnascufcFeGce0mbaaaQcdtfydba39hmekdna8Acv2asfc:W1jjbfRbbTmbaCaQcdtfydbaCa3cdtfydb0mekJbbacJbbjZasceSEhIa8AceShOa8JaeaLc:K1jjbfydba5fcdtfydbcx2fhsdna8JaQcx2fg8AIdwa8Ja3cx2fgKIdwgy:tg8Pa8PNa8AIdbaKIdbgR:tg8Na8NNa8AIdlaKIdlg8R:tg8Sa8SNMM:rg8MJbbbb9ETmba8Pa8M:vh8Pa8Sa8M:vh8Sa8Na8M:vh8NkJbbacaIaOEh8WdnasIdway:tgIa8PaIa8PNasIdbaR:tg8Xa8NNa8SasIdla8R:tg8VNMMg8UN:tgIaINa8Xa8Na8UN:tg8Pa8PNa8Va8Sa8UN:tg8Na8NNMM:rg8SJbbbb9ETmbaIa8S:vhIa8Na8S:vh8Na8Pa8S:vh8Pka8EaCa3cdtfydbc8S2fgsa8Pa8Wa8MNg8Sa8PNNg8UasIdbMUdbasa8Na8Sa8NNg8WNg8XasIdlMUdlasaIa8SaINg8MNg8VasIdwMUdwasa8Wa8PNg8WasIdxMUdxasa8Ma8PNg8YasIdzMUdzasa8Ma8NNg8ZasIdCMUdCasa8Pa8SaIayNa8PaRNa8Ra8NNMM:mgyNg8MNg8PasIdKMUdKasa8Na8MNg8NasId3MUd3asaIa8MNgIasIdaMUdaasa8MayNg8MasId8KMUd8Kasa8SasIdyMUdya8EaCaQcdtfydbc8S2fgsa8UasIdbMUdbasa8XasIdlMUdlasa8VasIdwMUdwasa8WasIdxMUdxasa8YasIdzMUdzasa8ZasIdCMUdCasa8PasIdKMUdKasa8NasId3MUd3asaIasIdaMUdaasa8MasId8KMUd8Kasa8SasIdyMUdykaLclfgLcx9hmbkaYcxfhYa5cifg5ad6mbkaDTmbcbhYinJbbbbhRa8JaeaYcdtfgsclfydbgKcx2fgLIdwa8JasydbgOcx2fgQIdwg8V:tg8Na8NNaLIdbaQIdbg8Y:tgIaINaLIdlaQIdlg8Z:tg8Sa8SNMMg8Wa8Jascwfydbggcx2fgsIdwa8V:tg8MNa8Na8Na8MNaIasIdba8Y:tgyNa8SasIdla8Z:tg8RNMMg8PN:tJbbbbJbbjZa8Wa8Ma8MNayayNa8Ra8RNMMg8XNa8Pa8PN:tg8U:va8UJbbbb9BEg8UNh80a8Xa8NNa8Ma8PN:ta8UNh81a8Wa8RNa8Sa8PN:ta8UNhBa8Xa8SNa8Ra8PN:ta8UNh83a8WayNaIa8PN:ta8UNhUa8XaINaya8PN:ta8UNh85aIa8RNaya8SN:tg8Pa8PNa8Sa8MNa8Ra8NN:tg8Pa8PNa8NayNa8MaIN:tg8Pa8PNMM:r:rh8PavaOaD2cdtfhLavagaD2cdtfhQavaKaD2cdtfh3a8V:mh86a8Z:mh87a8Y:mh88cbh8AaDh5Jbbbbh8RJbbbbh8UJbbbbh8WJbbbbh8XJbbbbh8VJbbbbh8YJbbbbh8ZJbbbbh89Jbbbbh8:inaPc;Wbfa8Afgscwfa8Pa81a3IdbaLIdbg8M:tg8SNa80aQIdba8M:tgyNMg8NNUdbasclfa8Pa83a8SNaBayNMgINUdbasa8Pa85a8SNaUayNMg8SNUdbascxfa8Pa86a8NNa87aINa8Ma88a8SNMMMg8MNUdba8Pa8NaINNa8XMh8Xa8Pa8Na8SNNa8VMh8Va8PaIa8SNNa8YMh8Ya8Pa8Ma8MNNaRMhRa8Pa8Na8MNNa8RMh8Ra8PaIa8MNNa8UMh8Ua8Pa8Sa8MNNa8WMh8Wa8Pa8Na8NNNa8ZMh8Za8PaIaINNa89Mh89a8Pa8Sa8SNNa8:Mh8:aLclfhLa3clfh3aQclfhQa8Aczfh8Aa5cufg5mbkaoaCaOcdtfydbgLc8S2fgsa8:asIdbMUdbasa89asIdlMUdlasa8ZasIdwMUdwasa8YasIdxMUdxasa8VasIdzMUdzasa8XasIdCMUdCasa8WasIdKMUdKasa8UasId3MUd3asa8RasIdaMUdaasaRasId8KMUd8Kasa8PasIdyMUdyaoaCaKcdtfydbgKc8S2fgsa8:asIdbMUdbasa89asIdlMUdlasa8ZasIdwMUdwasa8YasIdxMUdxasa8VasIdzMUdzasa8XasIdCMUdCasa8WasIdKMUdKasa8UasId3MUd3asa8RasIdaMUdaasaRasId8KMUd8Kasa8PasIdyMUdyaoaCagcdtfydbgOc8S2fgsa8:asIdbMUdbasa89asIdlMUdlasa8ZasIdwMUdwasa8YasIdxMUdxasa8VasIdzMUdzasa8XasIdCMUdCasa8WasIdKMUdKasa8UasId3MUd3asa8RasIdaMUdaasaRasId8KMUd8Kasa8PasIdyMUdyawaLaD2cltfh5cbhLaDh3ina5aLfgsaPc;WbfaLfgQIdbasIdbMUdbasclfg8AaQclfIdba8AIdbMUdbascwfg8AaQcwfIdba8AIdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa3cufg3mbkawaKaD2cltfh5cbhLaDh3ina5aLfgsaPc;WbfaLfgQIdbasIdbMUdbasclfg8AaQclfIdba8AIdbMUdbascwfg8AaQcwfIdba8AIdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa3cufg3mbkawaOaD2cltfh5cbhLaDh3ina5aLfgsaPc;WbfaLfgQIdbasIdbMUdbasclfg8AaQclfIdba8AIdbMUdbascwfg8AaQcwfIdba8AIdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa3cufg3mbkaYcifgYad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkaPydbhZcbhsdnalTmbaZclfhsaZydbh3aEhLalh8AcbhQincbasydbg5a39RaLRbbcpeGEaQfhQaLcefhLasclfhsa5h3a8Acufg8AmbkaQce4hskcuadas9Rcifgrcx2arc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8LaPcwfaPyd9Ogscdtfa8LBdbaPascefgLBd9OaPcwfaLcdtfcuarcdtarcFFFFi0Ecbyd1:jjjbHjjjjbbgxBdbaPascdfgLBd9OaPcwfaLcdtfaAcbyd1:jjjbHjjjjbbgHBdbaPascifgLBd9OaPcwfaLcdtfalcbyd1:jjjbHjjjjbbgnBdbaPasclfBd9OJbbbbh8Ydnadaq9nmbdnarci6mbakakNh8VaDclthca8Lcwfh9cJbbbbh8YinaPabadghalaCz:cjjjbabhOcbhzcbhKincbhsindnaCaOasfydbgQcdtgYfydbg8AaCabasc;m1jjbfydbaKfcdtfydbgLcdtfydbg5SmbaEaLfRbbgecv2aEaQfRbbg3fc;G1jjbfRbbg8Ka3cv2aefggc;G1jjbfRbbgiVcFeGTmbdnagc:W1jjbfRbbTmba5a8A0mekdna3ae9hmba3cufcFeGce0mba8FaYfydbaL9hmeka8Lazcx2fg3aLaQaicFeGg8AEBdla3aQaLa8AEBdba3a8Aa8KGcb9hBdwazcefhzkasclfgscx9hmbkdnaKcifgKah9pmbaOcxfhOazcifar9nmekkdnazmbahhdxikcbheinJbbbbJbbjZa8EaCa8Laecx2fg3ydlg8Aa3ydbg5a3ydwgLEgKcdtfydbg8Kc8S2gifgsIdyg8P:va8PJbbbb9BEasIdwa8Ja5a8AaLEgYcx2fgLIdwg8SNasIdzaLIdbg8MNasIdaMg8Pa8PMMa8SNasIdlaLIdlgyNasIdCa8SNasId3Mg8Pa8PMMayNasIdba8MNasIdxayNasIdKMg8Pa8PMMa8MNasId8KMMM:lNh8WJbbbbJbbjZa8EaCa5cdtfydbgdc8S2gQfgsIdyg8P:va8PJbbbb9BEasIdwa8Ja8Acx2fgLIdwgINasIdzaLIdbgRNasIdaMg8Pa8PMMaINasIdlaLIdlg8RNasIdCaINasId3Mg8Pa8PMMa8RNasIdbaRNasIdxa8RNasIdKMg8Pa8PMMaRNasId8KMMM:lNh8Xa3cwfhOa3clfhgdnaDTmbaoaQfgQIdwaINaQIdzaRNaQIdaMg8Pa8PMMaINaQIdla8RNaQIdCaINaQId3Mg8Pa8PMMa8RNaQIdbaRNaQIdxa8RNaQIdKMg8Pa8PMMaRNaQId8KMMMh8Nava8AaD2cdtfhLawadaD2cltfhsaQIdyh8UaDhQinaLIdbg8PJbbb;aNascxfIdbaIascwfIdbNaRasIdbNa8RasclfIdbNMMMNa8Pa8PNa8UNa8NMMh8NaLclfhLasczfhsaQcufgQmbkaoaifgQIdwa8SNaQIdza8MNaQIdaMg8Pa8PMMa8SNaQIdlayNaQIdCa8SNaQId3Mg8Pa8PMMayNaQIdba8MNaQIdxayNaQIdKMg8Pa8PMMa8MNaQId8KMMMhIavaYaD2cdtfhLawa8KaD2cltfhsaQIdyhRaDhQinaLIdbg8PJbbb;aNascxfIdba8SascwfIdbNa8MasIdbNayasclfIdbNMMMNa8Pa8PNaRNaIMMhIaLclfhLasczfhsaQcufgQmbka8WaI:lMh8Wa8Xa8N:lMh8Xkaga8AaYa8Xa8W9FgsEBdba3a5aKasEBdbaOa8Xa8WasEUdbaecefgeaz9hmbkaPc;Wbfcbcj;abz:ljjjb8Aa9chsazhLinaPc;WbfasydbcO4c;8ZGfgQaQydbcefBdbascxfhsaLcufgLmbkcbhscbhLinaPc;WbfasfgQydbh3aQaLBdba3aLfhLasclfgscj;ab9hmbkcbhsa9chLinaPc;WbfaLydbcO4c;8ZGfgQaQydbgQcefBdbaxaQcdtfasBdbaLcxfhLazascefgs9hmbkahaq9RgQci9UhJdnalTmbcbhsaHhLinaLasBdbaLclfhLalascefgs9hmbkkcbh9eancbalz:ljjjbhTaQcO9UhSaJce4h9haPydlh9icbhicbhgdnina8Laxagcdtfydbcx2fgOIdwg8Na8V9EmeaiaJ9pmeJFFuuh8Pdna9haz9pmba8Laxa9hcdtfydbcx2fIdwJbb;aZNh8Pkdna8Na8P9ETmbaiaS0mdkdnaTaCaOydlg6cdtg9kfydbg3fg0RbbaTaCaOydbgKcdtg9mfydbg9nfg9oRbbVmbdnaZa9ncdtfgsclfydbgLasydbgsSmbaLas9Rh5a9iascitfhsa8Ja3cx2fgYcwfhdaYclfhAa8Ja9ncx2fg8Kcwfh9pa8Kclfh9qcbhLcehednindnaHasydbcdtfydbgQa3SmbaHasclfydbcdtfydbg8Aa3SmbaQa8ASmba8Ja8Acx2fg8AIdba8JaQcx2fgQIdbgI:tg8Pa9qIdbaQIdlg8S:tg8MNa8KIdbaI:tgya8AIdla8S:tg8NN:ta8PaAIdba8S:tgRNaYIdbaI:tg8Ra8NN:tNa8Na9pIdbaQIdwg8S:tg8UNa8Ma8AIdwa8S:tgIN:ta8NadIdba8S:tg8SNaRaIN:tNaIayNa8Ua8PN:taIa8RNa8Sa8PN:tNMMJbbbb9FmdkascwfhsaLcefgLa56hea5aL9hmbkkaeceGTmba9hcefh9hxeka8Ea3c8S2gQfgsa8Ea9nc8S2g8AfgLIdbasIdbMUdbasaLIdlasIdlMUdlasaLIdwasIdwMUdwasaLIdxasIdxMUdxasaLIdzasIdzMUdzasaLIdCasIdCMUdCasaLIdKasIdKMUdKasaLId3asId3MUd3asaLIdaasIdaMUdaasaLId8KasId8KMUd8KasaLIdyasIdyMUdydnaDTmbaoaQfgsaoa8AfgLIdbasIdbMUdbasaLIdlasIdlMUdlasaLIdwasIdwMUdwasaLIdxasIdxMUdxasaLIdzasIdzMUdzasaLIdCasIdCMUdCasaLIdKasIdKMUdKasaLId3asId3MUd3asaLIdaasIdaMUdaasaLId8KasId8KMUd8KasaLIdyasIdyMUdyaca9n2heaca32hYawhLaDh8AinaLaYfgsaLaefgQIdbasIdbMUdbasclfg5aQclfIdba5IdbMUdbascwfg5aQcwfIdba5IdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa8Acufg8AmbkkaOcwfhLdndndndnaEaKfgQRbbc9:fPdebdkaKhsinaHascdtgsfa3BdbaXasfydbgsaK9hmbxikkaXa9kfydbhsaXa9mfydbhKaHa9mfa6Bdbash6kaHaKcdtfa6Bdbka9oce86bba0ce86bbaLIdbg8Pa8Ya8Ya8P9DEh8Ya9ecefh9ececdaQRbbceSEaifhikagcefggaz9hmbkkdna9embahhdxikdnalTmbcbhLa8FhsindnasydbgQcuSmbdnaLaHaQcdtg3fydbgQ9hmba8Fa3fydbhQkasaQBdbkasclfhsalaLcefgL9hmbkcbhLaahsindnasydbgQcuSmbdnaLaHaQcdtg3fydbgQ9hmbaaa3fydbhQkasaQBdbkasclfhsalaLcefgL9hmbkkcbhdabhscbh8AindnaHasydbcdtfydbgLaHasclfydbcdtfydbgQSmbaLaHascwfydbcdtfydbg3SmbaQa3Smbabadcdtfg5aLBdba5clfaQBdba5cwfa3Bdbadcifhdkascxfhsa8Acifg8Aah6mbkadaq9nmdxbkkaPabadalaCz:cjjjbkdnamTmbama8Y:rUdbkaPyd9OgscdtaPcwffc98fhCdninasTmeaCydbcbyd:m:jjjbH:bjjjbbaCc98fhCascufhsxbkkaPc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8KbabaeadaialavcbcbcbcbaoarawaDz:bjjjbk8KbabaeadaialavaoarawaDaqakaxamz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; + var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;H9Usdbk;N6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascwfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd1:jjjbHjjjjbbgHBdwasceBd9OasaHBdbascuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgOBdxascdBd9OasaOBdlasaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd1:jjjbHjjjjbbgXBdzasciBd9OasaCcbyd1:jjjbHjjjjbbgQBdCasclBd9Oalcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd1:jjjbHjjjjbbgLBdKascvBd9OaLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd:m:jjjbH:bjjjbbasclBd9Oasalcbyd1:jjjbHjjjjbbg3BdKascvBd9OasaCcbyd1:jjjbHjjjjbbgzBd3ascoBd9OasaCcbyd1:jjjbHjjjjbbgKBdaascrBd9OazcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Kascwfasyd9Ogzcdtfa8KBdbasazcefgABd9Oa8Kaialavz:djjjbdndnaDmbcbhvxekcbh8EascwfaAcdtfcuaDal2gKcdtaKcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbasazcdfgABd9OalTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascwfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd1:jjjbHjjjjbbgKBdbasaAcefg5Bd9OaKcbazz:ljjjbh8FdndndnaDTmbascwfa5cdtfaLcbyd1:jjjbHjjjjbbgoBdbasaAcdfgKBd9Oaocbazz:ljjjb8AascwfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd1:jjjbHjjjjbbgqBdbasaAcifBd9OaqcbaKz:ljjjb8AadmexdkcbhocbhqadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Eaeh8AincbhKina3aeaKc:G1jjbfydba8EfcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:W1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekJbbacJbbjZazceSEh8RaEceShAa8KaeaKc:K1jjbfydba8Efcdtfydbcx2fhzdna8KaLcx2fgEIdwa8Ka5cx2fgYIdwg8P:tgIaINaEIdbaYIdbg8U:tgyayNaEIdlaYIdlg8S:tgRaRNMM:rg8NJbbbb9ETmbaIa8N:vhIaRa8N:vhRaya8N:vhykJbbaca8RaAEh8XdnazIdwa8P:tg8RaIa8RaINazIdba8U:tg8YayNaRazIdla8S:tg8WNMMg8VN:tg8Ra8RNa8Yaya8VN:tgIaINa8WaRa8VN:tgyayNMM:rgRJbbbb9ETmba8RaR:vh8RayaR:vhyaIaR:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNgRaINNg8VazIdbMUdbazayaRayNg8XNg8YazIdlMUdlaza8RaRa8RNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIaRa8Ra8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3aza8Ra8NNg8RazIdaMUdaaza8Na8PNg8NazId8KMUd8KazaRazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3aza8RazIdaMUdaaza8NazId8KMUd8KazaRazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Ecifg8Ead6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tg8Ra8RNaKIdlaLIdlg80:tgRaRNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNa8RazIdba8Z:tg8PNaRazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNaRaIN:ta8VNh83a8YaRNa8SaIN:ta8VNhUa8Xa8PNa8RaIN:ta8VNh85a8Ya8RNa8PaIN:ta8VNh86a8Ra8SNa8PaRN:tgIaINaRa8NNa8SayN:tgIaINaya8PNa8Na8RN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tgRNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUaRNa83a8PNMg8RNUdbazaIa86aRNa85a8PNMgRNUdbazcxfaIa87ayNa88a8RNa8Na89aRNMMMg8NNUdbaIaya8RNNa8YMh8YaIayaRNNa8WMh8WaIa8RaRNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIa8Ra8NNNa8VMh8VaIaRa8NNNa8XMh8XaIayayNNa80Mh80aIa8Ra8RNNa8:Mh8:aIaRaRNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaoaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydbhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Mascwfasyd9Ogzcdtfa8MBdbasazcefgKBd9OascwfaKcdtfcuamcdtamcFFFFi0Ecbyd1:jjjbHjjjjbbgwBdbasazcdfgKBd9OascwfaKcdtfaCcbyd1:jjjbHjjjjbbgOBdbasazcifgKBd9OascwfaKcdtfalcbyd1:jjjbHjjjjbbgcBdbasazclfBd9OJbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasabadggalaXz:cjjjbabhAcbhHcbhYincbhzindnaXaAazfydbgLcdtg8AfydbgEaXabazc;m1jjbfydbaYfcdtfydbgKcdtfydbg8ESmba3aKfRbbgecv2a3aLfRbbg5fc;G1jjbfRbbg8La5cv2aefg8Jc;G1jjbfRbbgiVcFeGTmbdna8Jc:W1jjbfRbbTmba8EaE0mekdna5ae9hmba5cufcFeGce0mbaaa8AfydbaK9hmeka8MaHcx2fg5aKaLaicFeGgEEBdla5aLaKaEEBdba5aEa8LGcb9hBdwaHcefhHkazclfgzcx9hmbkdnaYcifgYag9pmbaAcxfhAaHcifam9nmekkdnaHmbaghdxikcbheinJbbbbJbbjZa8FaXa8Maecx2fg5ydlgEa5ydbg8Ea5ydwgKEgYcdtfydbg8Lc8S2gifgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEg8Acx2fgKIdwgRNazIdzaKIdbg8NNazIdaMgIaIMMaRNazIdlaKIdlg8PNazIdCaRNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbgdc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwg8RNazIdzaKIdbg8UNazIdaMgIaIMMa8RNazIdlaKIdlg8SNazIdCa8RNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfhAa5clfh8JdnaDTmbaoaLfgLIdwa8RNaLIdza8UNaLIdaMgIaIMMa8RNaLIdla8SNaLIdCa8RNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKaqadaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaoaifgLIdwaRNaLIdza8NNaLIdaMgIaIMMaRNaLIdla8PNaLIdCaRNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMh8Rava8AaD2cdtfhKaqa8LaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNa8RMMh8RaKclfhKazczfhzaLcufgLmbka8Xa8R:lMh8Xa8Yay:lMh8Yka8JaEa8Aa8Ya8X9FgzEBdba5a8EaYazEBdbaAa8Ya8XazEUdbaecefgeaH9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzaHhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbawaLcdtfazBdbaKcxfhKaHazcefgz9hmbkagak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydlh6cbhicbh8Jdnina8Mawa8Jcdtfydbcx2fgAIdwgya8W9Emeaia9e9pmeJFFuuhIdna9iaH9pmba8Mawa9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaia9h0mdkdnaSaXaAydlg9kcdtg0fydbg5fg9mRbbaSaXaAydbgYcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fg8Acwfhda8AclfhCa8Ka9ocx2fg8Lcwfhra8Lclfh9qcbhKcehednindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbg8R:tgIa9qIdbaLIdlgR:tg8NNa8LIdba8R:tg8PaEIdlaR:tgyN:taIaCIdbaR:tg8UNa8AIdba8R:tg8SayN:tNayarIdbaLIdwgR:tg8VNa8NaEIdwaR:tg8RN:tayadIdbaR:tgRNa8Ua8RN:tNa8Ra8PNa8VaIN:ta8Ra8SNaRaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6hea8EaK9hmbkkaeceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaoaLfgzaoaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2hea9ca52h8AaqhKaDhEinaKa8AfgzaKaefgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkkaAcwfhKdndndndna3aYfgLRbbc9:fPdebdkaYhzinaOazcdtgzfa5BdbaQazfydbgzaY9hmbxikkaQa0fydbhzaQa9nfydbhYaOa9nfa9kBdbazh9kkaOaYcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaifhika8Jcefg8JaH9hmbkkdnaTmbaghdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8EclfaLBdba8Ecwfa5BdbadcifhdkazcxfhzaEcifgEag6mbkadak9nmdxbkkasabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd9Ogzcdtascwffc98fhXdninazTmeaXydbcbyd:m:jjjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; - var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); + var wasmpack = new Uint8Array([32, 0, 65, 2, 1, 106, 34, 33, 3, 128, 11, 4, 13, 64, 6, 253, 10, 7, 15, 116, 127, 5, 8, 12, 40, 16, 19, 54, 20, 9, 27, 255, 113, 17, 42, 67, 24, 23, 146, 148, 18, 14, 22, 45, 70, 69, 56, 114, 101, 21, 25, 63, 75, 136, 108, 28, 118, 29, 73, 115]); if (typeof WebAssembly !== 'object') { return { @@ -18,10 +18,10 @@ var MeshoptSimplifier = (function() { var ready = WebAssembly.instantiate(unpack(wasm), {}) - .then(function(result) { - instance = result.instance; - instance.exports.__wasm_call_ctors(); - }); + .then(function (result) { + instance = result.instance; + instance.exports.__wasm_call_ctors(); + }); function unpack(data) { var result = new Uint8Array(data.length); @@ -96,7 +96,7 @@ var MeshoptSimplifier = (function() { return [target, error[0]]; } - function simplifyAttr(fun, indices, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, target_index_count, target_error, options) { + function simplifyAttr(fun, indices, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, options) { var sbrk = instance.exports.sbrk; var te = sbrk(4); var ti = sbrk(index_count * 4); @@ -104,12 +104,15 @@ var MeshoptSimplifier = (function() { var sa = sbrk(vertex_count * vertex_attributes_stride); var sw = sbrk(attribute_weights.length * 4); var si = sbrk(index_count * 4); + var vl = vertex_lock && sbrk(vertex_count); var heap = new Uint8Array(instance.exports.memory.buffer); heap.set(bytes(vertex_positions), sp); heap.set(bytes(vertex_attributes), sa); heap.set(bytes(attribute_weights), sw); heap.set(bytes(indices), si); - var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, sa, vertex_attributes_stride, sw, attribute_weights.length, target_index_count, target_error, options, te); + if (vertex_lock) + heap.set(bytes(vertex_lock), vl); + var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, sa, vertex_attributes_stride, sw, attribute_weights.length, vl, target_index_count, target_error, options, te); // heap may have grown heap = new Uint8Array(instance.exports.memory.buffer); var target = new Uint32Array(result); @@ -161,7 +164,7 @@ var MeshoptSimplifier = (function() { // note that these functions are experimental and may change interface/behavior in a way that will require revising calling code useExperimentalFeatures: false, - compactMesh: function(indices) { + compactMesh: function (indices) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -169,7 +172,7 @@ var MeshoptSimplifier = (function() { return reorder(instance.exports.meshopt_optimizeVertexFetchRemap, indices32, maxindex(indices) + 1); }, - simplify: function(indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { + simplify: function (indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); assert(vertex_positions instanceof Float32Array); @@ -191,7 +194,7 @@ var MeshoptSimplifier = (function() { return result; }, - simplifyWithAttributes: function(indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, target_index_count, target_error, flags) { + simplifyWithAttributes: function (indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, flags) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -201,6 +204,7 @@ var MeshoptSimplifier = (function() { assert(vertex_attributes instanceof Float32Array); assert(vertex_attributes.length % vertex_attributes_stride == 0); assert(vertex_attributes_stride >= 0); + assert(vertex_lock == null || vertex_lock.length == vertex_positions.length); assert(target_index_count >= 0 && target_index_count <= indices.length); assert(target_index_count % 3 == 0); assert(target_error >= 0 && target_error <= 1); @@ -213,21 +217,24 @@ var MeshoptSimplifier = (function() { options |= simplifyOptions[flags[i]]; } + if (vertex_lock) + vertex_lock = new Uint8Array(vertex_lock); + var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices); - var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), target_index_count, target_error, options); + var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), vertex_lock, target_index_count, target_error, options); result[0] = (indices instanceof Uint32Array) ? result[0] : new indices.constructor(result[0]); return result; }, - getScale: function(vertex_positions, vertex_positions_stride) { + getScale: function (vertex_positions, vertex_positions_stride) { assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); assert(vertex_positions_stride >= 3); return simplifyScale(instance.exports.meshopt_simplifyScale, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4); }, - simplifyPoints: function(vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { + simplifyPoints: function (vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); @@ -250,7 +257,7 @@ var MeshoptSimplifier = (function() { if (typeof exports === 'object' && typeof module === 'object') module.exports = MeshoptSimplifier; else if (typeof define === 'function' && define['amd']) - define([], function() { + define([], function () { return MeshoptSimplifier; }); else if (typeof exports === 'object') diff --git a/js/meshopt_simplifier.module.d.ts b/js/meshopt_simplifier.module.d.ts index fe4c0e82b4..6c2bdf8374 100644 --- a/js/meshopt_simplifier.module.d.ts +++ b/js/meshopt_simplifier.module.d.ts @@ -7,13 +7,13 @@ export const MeshoptSimplifier: { ready: Promise; useExperimentalFeatures: boolean; - + compactMesh: (indices: Uint32Array) => [Uint32Array, number]; - + simplify: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; // Experimental; requires useExperimentalFeatures to be set to true - simplifyWithAttributes: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, vertex_attributes: Float32Array, vertex_attributes_stride: number, attribute_weights: number[], target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; + simplifyWithAttributes: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, vertex_attributes: Float32Array, vertex_attributes_stride: number, attribute_weights: number[], vertex_lock: boolean[], target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; getScale: (vertex_positions: Float32Array, vertex_positions_stride: number) => number; diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index a6c5be8d38..6232b2e50a 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -1,11 +1,11 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -var MeshoptSimplifier = (function() { +var MeshoptSimplifier = (function () { // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 - var wasm = "b9H79Tebbbe9Ek9Geueu9Geub9Gbb9GPuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq::9Usdbk;i6iKuY99Ou8Jjjjjbc;W;ab9RgP8KjjjjbaPcwfcbc;Kbz:ljjjb8AaPcualcefgscdtascFFFFi0Ecbyd1:jjjbHjjjjbbgzBdwaPceBd9OaPazBdbaPcuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgHBdxaPcdBd9OaPaHBdlaPaeadalcbz:cjjjbaPcualcdtgOalcFFFFi0EgAcbyd1:jjjbHjjjjbbgCBdzaPciBd9OaPaAcbyd1:jjjbHjjjjbbgXBdCaPclBd9Oalcd4alfhQcehLinaLgscethLasaQ6mbkcbhKaPcuascdtgLascFFFFi0Ecbyd1:jjjbHjjjjbbgQBdKaPcvBd9OaQcFeaLz:ljjjbhYdnalTmbavcd4h8AascufhEinaiaKa8A2cdtfg3ydlgscH4as7c:F:b:DD2a3ydbgscH4as7c;D;O:B8J27a3ydwgscH4as7c:3F;N8N27hQcbhsdndninaYaQaEGgQcdtfg5ydbgLcuSmeaiaLa8A2cdtfa3cxz:ojjjbTmdascefgsaQfhQasaE9nmbxdkka5aKBdbaKhLkaCaKcdtfaLBdbaKcefgKal9hmbkcbhsaXhLinaLasBdbaLclfhLalascefgs9hmbkcbhsaChLaXhQindnasaLydbgESmbaQaXaEcdtfgEydbBdbaEasBdbkaLclfhLaQclfhQalascefgs9hmbkkcbh8EaYcbyd:m:jjjbH:bjjjbbaPclBd9OaPalcbyd1:jjjbHjjjjbbgEBdKaPcvBd9OaPaAcbyd1:jjjbHjjjjbbgsBd3aPcoBd9OaPaAcbyd1:jjjbHjjjjbbgLBdaaPcrBd9OascFeaOz:ljjjbh8FaLcFeaOz:ljjjbhadnalTmbaHcwfhhindnaza8EgQcefg8Ecdtfydbg3azaQcdtgsfydbgLSmba3aL9RhOaHaLcitfhgaaasfh8Ja8FasfhKcbh8Aindndnaga8Acitfydbg5aQ9hmbaKaQBdba8JaQBdbxekdnaza5cdtg8KfgsclfydbgLasydbgsSmbaHascitg3fydbaQSmeaLas9Rh8Lascu7aLfhYaha3fhLcbhsinaYasSmeascefhsaLydbh3aLcwfhLa3aQ9hmbkasa8L6mekaaa8KfgsaQa5asydbcuSEBdbaKa5aQaKydbcuSEBdbka8Acefg8AaO9hmbkka8Eal9hmbkaChLaXhQaah3a8Fh8AcbhsindndnasaLydbg59hmbdnasaQydbg59hmba8Aydbh5dna3ydbgYcu9hmba5cu9hmbaEasfcb86bbxikaEasfhKdnasaYSmbasa5SmbaKce86bbxikaKcl86bbxdkdnasaXa5cdtgYfydb9hmbdna3ydbgKcuSmbasaKSmba8AydbgOcuSmbasaOSmbaaaYfydbggcuSmbaga5Smba8FaYfydbgYcuSmbaYa5SmbdnaCaKcdtfydbaCaYcdtfydb9hmbaCaOcdtfydbaCagcdtfydb9hmbaEasfcd86bbxlkaEasfcl86bbxikaEasfcl86bbxdkaEasfcl86bbxekaEasfaEa5fRbb86bbkaLclfhLaQclfhQa3clfh3a8Aclfh8Aalascefgs9hmbkaxceGTmbaEhsalhLindnasRbbce9hmbascl86bbkascefhsaLcufgLmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8JaPcwfaPyd9Ogscdtfa8JBdbaPascefgOBd9Oa8Jaialavz:djjjbdndnaDmbcbhvxekcbh5aPcwfaOcdtfcuaDal2gLcdtaLcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbaPascdfgOBd9OalTmbarcd4cdthYaDcdthKavh8AinaohsawhLa8AhQaDh3inaQasIdbaLIdbNUdbasclfhsaLclfhLaQclfhQa3cufg3mbkaoaYfhoa8AaKfh8Aa5cefg5al9hmbkkaPcwfaOcdtfcualc8S2gsalc;D;O;f8U0EgQcbyd1:jjjbHjjjjbbgLBdbaPaOcefg3Bd9OaLcbasz:ljjjbh8EdndndnaDTmbaPcwfa3cdtfaQcbyd1:jjjbHjjjjbbgoBdbaPaOcdfgLBd9Oaocbasz:ljjjb8AaPcwfaLcdtfcuaDal2gscltgLascFFFFb0Ecbyd1:jjjbHjjjjbbgwBdbaPaOcifBd9OawcbaLz:ljjjb8AadmexdkcbhocbhwadTmekcbh8AaehLindna8JaLclfydbg5cx2fgsIdba8JaLydbgYcx2fgQIdbg8M:tg8Na8JaLcwfydbgKcx2fg3IdlaQIdlgy:tg8PNa3Idba8M:tgIasIdlay:tg8RN:tg8Sa8SNa8Ra3IdwaQIdwgR:tg8UNa8PasIdwaR:tg8RN:tg8Pa8PNa8RaINa8Ua8NN:tg8Na8NNMM:rgIJbbbb9ETmba8SaI:vh8Sa8NaI:vh8Na8PaI:vh8Pka8EaCaYcdtfydbc8S2fgsa8PaI:rgIa8PNNg8RasIdbMUdbasa8NaIa8NNg8VNg8UasIdlMUdlasa8SaIa8SNg8WNg8XasIdwMUdwasa8Va8PNg8VasIdxMUdxasa8Wa8PNg8YasIdzMUdzasa8Wa8NNg8WasIdCMUdCasa8PaIa8SaRNa8Pa8MNaya8NNMM:mgyNg8MNg8PasIdKMUdKasa8Na8MNg8NasId3MUd3asa8Sa8MNg8SasIdaMUdaasa8MayNg8MasId8KMUd8KasaIasIdyMUdya8EaCa5cdtfydbc8S2fgsa8RasIdbMUdbasa8UasIdlMUdlasa8XasIdwMUdwasa8VasIdxMUdxasa8YasIdzMUdzasa8WasIdCMUdCasa8PasIdKMUdKasa8NasId3MUd3asa8SasIdaMUdaasa8MasId8KMUd8KasaIasIdyMUdya8EaCaKcdtfydbc8S2fgsa8RasIdbMUdbasa8UasIdlMUdlasa8XasIdwMUdwasa8VasIdxMUdxasa8YasIdzMUdzasa8WasIdCMUdCasa8PasIdKMUdKasa8NasId3MUd3asa8SasIdaMUdaasa8MasId8KMUd8KasaIasIdyMUdyaLcxfhLa8Acifg8Aad6mbkcbh5aehYincbhLinaEaeaLc:G1jjbfydba5fcdtfydbgQfRbbhsdndnaEaYaLfydbg3fRbbg8Ac99fcFeGcpe0mbasceSmbascd9hmekdna8AcufcFeGce0mba8Fa3cdtfydbaQ9hmekdnascufcFeGce0mbaaaQcdtfydba39hmekdna8Acv2asfc:W1jjbfRbbTmbaCaQcdtfydbaCa3cdtfydb0mekJbbacJbbjZasceSEhIa8AceShOa8JaeaLc:K1jjbfydba5fcdtfydbcx2fhsdna8JaQcx2fg8AIdwa8Ja3cx2fgKIdwgy:tg8Pa8PNa8AIdbaKIdbgR:tg8Na8NNa8AIdlaKIdlg8R:tg8Sa8SNMM:rg8MJbbbb9ETmba8Pa8M:vh8Pa8Sa8M:vh8Sa8Na8M:vh8NkJbbacaIaOEh8WdnasIdway:tgIa8PaIa8PNasIdbaR:tg8Xa8NNa8SasIdla8R:tg8VNMMg8UN:tgIaINa8Xa8Na8UN:tg8Pa8PNa8Va8Sa8UN:tg8Na8NNMM:rg8SJbbbb9ETmbaIa8S:vhIa8Na8S:vh8Na8Pa8S:vh8Pka8EaCa3cdtfydbc8S2fgsa8Pa8Wa8MNg8Sa8PNNg8UasIdbMUdbasa8Na8Sa8NNg8WNg8XasIdlMUdlasaIa8SaINg8MNg8VasIdwMUdwasa8Wa8PNg8WasIdxMUdxasa8Ma8PNg8YasIdzMUdzasa8Ma8NNg8ZasIdCMUdCasa8Pa8SaIayNa8PaRNa8Ra8NNMM:mgyNg8MNg8PasIdKMUdKasa8Na8MNg8NasId3MUd3asaIa8MNgIasIdaMUdaasa8MayNg8MasId8KMUd8Kasa8SasIdyMUdya8EaCaQcdtfydbc8S2fgsa8UasIdbMUdbasa8XasIdlMUdlasa8VasIdwMUdwasa8WasIdxMUdxasa8YasIdzMUdzasa8ZasIdCMUdCasa8PasIdKMUdKasa8NasId3MUd3asaIasIdaMUdaasa8MasId8KMUd8Kasa8SasIdyMUdykaLclfgLcx9hmbkaYcxfhYa5cifg5ad6mbkaDTmbcbhYinJbbbbhRa8JaeaYcdtfgsclfydbgKcx2fgLIdwa8JasydbgOcx2fgQIdwg8V:tg8Na8NNaLIdbaQIdbg8Y:tgIaINaLIdlaQIdlg8Z:tg8Sa8SNMMg8Wa8Jascwfydbggcx2fgsIdwa8V:tg8MNa8Na8Na8MNaIasIdba8Y:tgyNa8SasIdla8Z:tg8RNMMg8PN:tJbbbbJbbjZa8Wa8Ma8MNayayNa8Ra8RNMMg8XNa8Pa8PN:tg8U:va8UJbbbb9BEg8UNh80a8Xa8NNa8Ma8PN:ta8UNh81a8Wa8RNa8Sa8PN:ta8UNhBa8Xa8SNa8Ra8PN:ta8UNh83a8WayNaIa8PN:ta8UNhUa8XaINaya8PN:ta8UNh85aIa8RNaya8SN:tg8Pa8PNa8Sa8MNa8Ra8NN:tg8Pa8PNa8NayNa8MaIN:tg8Pa8PNMM:r:rh8PavaOaD2cdtfhLavagaD2cdtfhQavaKaD2cdtfh3a8V:mh86a8Z:mh87a8Y:mh88cbh8AaDh5Jbbbbh8RJbbbbh8UJbbbbh8WJbbbbh8XJbbbbh8VJbbbbh8YJbbbbh8ZJbbbbh89Jbbbbh8:inaPc;Wbfa8Afgscwfa8Pa81a3IdbaLIdbg8M:tg8SNa80aQIdba8M:tgyNMg8NNUdbasclfa8Pa83a8SNaBayNMgINUdbasa8Pa85a8SNaUayNMg8SNUdbascxfa8Pa86a8NNa87aINa8Ma88a8SNMMMg8MNUdba8Pa8NaINNa8XMh8Xa8Pa8Na8SNNa8VMh8Va8PaIa8SNNa8YMh8Ya8Pa8Ma8MNNaRMhRa8Pa8Na8MNNa8RMh8Ra8PaIa8MNNa8UMh8Ua8Pa8Sa8MNNa8WMh8Wa8Pa8Na8NNNa8ZMh8Za8PaIaINNa89Mh89a8Pa8Sa8SNNa8:Mh8:aLclfhLa3clfh3aQclfhQa8Aczfh8Aa5cufg5mbkaoaCaOcdtfydbgLc8S2fgsa8:asIdbMUdbasa89asIdlMUdlasa8ZasIdwMUdwasa8YasIdxMUdxasa8VasIdzMUdzasa8XasIdCMUdCasa8WasIdKMUdKasa8UasId3MUd3asa8RasIdaMUdaasaRasId8KMUd8Kasa8PasIdyMUdyaoaCaKcdtfydbgKc8S2fgsa8:asIdbMUdbasa89asIdlMUdlasa8ZasIdwMUdwasa8YasIdxMUdxasa8VasIdzMUdzasa8XasIdCMUdCasa8WasIdKMUdKasa8UasId3MUd3asa8RasIdaMUdaasaRasId8KMUd8Kasa8PasIdyMUdyaoaCagcdtfydbgOc8S2fgsa8:asIdbMUdbasa89asIdlMUdlasa8ZasIdwMUdwasa8YasIdxMUdxasa8VasIdzMUdzasa8XasIdCMUdCasa8WasIdKMUdKasa8UasId3MUd3asa8RasIdaMUdaasaRasId8KMUd8Kasa8PasIdyMUdyawaLaD2cltfh5cbhLaDh3ina5aLfgsaPc;WbfaLfgQIdbasIdbMUdbasclfg8AaQclfIdba8AIdbMUdbascwfg8AaQcwfIdba8AIdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa3cufg3mbkawaKaD2cltfh5cbhLaDh3ina5aLfgsaPc;WbfaLfgQIdbasIdbMUdbasclfg8AaQclfIdba8AIdbMUdbascwfg8AaQcwfIdba8AIdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa3cufg3mbkawaOaD2cltfh5cbhLaDh3ina5aLfgsaPc;WbfaLfgQIdbasIdbMUdbasclfg8AaQclfIdba8AIdbMUdbascwfg8AaQcwfIdba8AIdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa3cufg3mbkaYcifgYad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkaPydbhZcbhsdnalTmbaZclfhsaZydbh3aEhLalh8AcbhQincbasydbg5a39RaLRbbcpeGEaQfhQaLcefhLasclfhsa5h3a8Acufg8AmbkaQce4hskcuadas9Rcifgrcx2arc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8LaPcwfaPyd9Ogscdtfa8LBdbaPascefgLBd9OaPcwfaLcdtfcuarcdtarcFFFFi0Ecbyd1:jjjbHjjjjbbgxBdbaPascdfgLBd9OaPcwfaLcdtfaAcbyd1:jjjbHjjjjbbgHBdbaPascifgLBd9OaPcwfaLcdtfalcbyd1:jjjbHjjjjbbgnBdbaPasclfBd9OJbbbbh8Ydnadaq9nmbdnarci6mbakakNh8VaDclthca8Lcwfh9cJbbbbh8YinaPabadghalaCz:cjjjbabhOcbhzcbhKincbhsindnaCaOasfydbgQcdtgYfydbg8AaCabasc;m1jjbfydbaKfcdtfydbgLcdtfydbg5SmbaEaLfRbbgecv2aEaQfRbbg3fc;G1jjbfRbbg8Ka3cv2aefggc;G1jjbfRbbgiVcFeGTmbdnagc:W1jjbfRbbTmba5a8A0mekdna3ae9hmba3cufcFeGce0mba8FaYfydbaL9hmeka8Lazcx2fg3aLaQaicFeGg8AEBdla3aQaLa8AEBdba3a8Aa8KGcb9hBdwazcefhzkasclfgscx9hmbkdnaKcifgKah9pmbaOcxfhOazcifar9nmekkdnazmbahhdxikcbheinJbbbbJbbjZa8EaCa8Laecx2fg3ydlg8Aa3ydbg5a3ydwgLEgKcdtfydbg8Kc8S2gifgsIdyg8P:va8PJbbbb9BEasIdwa8Ja5a8AaLEgYcx2fgLIdwg8SNasIdzaLIdbg8MNasIdaMg8Pa8PMMa8SNasIdlaLIdlgyNasIdCa8SNasId3Mg8Pa8PMMayNasIdba8MNasIdxayNasIdKMg8Pa8PMMa8MNasId8KMMM:lNh8WJbbbbJbbjZa8EaCa5cdtfydbgdc8S2gQfgsIdyg8P:va8PJbbbb9BEasIdwa8Ja8Acx2fgLIdwgINasIdzaLIdbgRNasIdaMg8Pa8PMMaINasIdlaLIdlg8RNasIdCaINasId3Mg8Pa8PMMa8RNasIdbaRNasIdxa8RNasIdKMg8Pa8PMMaRNasId8KMMM:lNh8Xa3cwfhOa3clfhgdnaDTmbaoaQfgQIdwaINaQIdzaRNaQIdaMg8Pa8PMMaINaQIdla8RNaQIdCaINaQId3Mg8Pa8PMMa8RNaQIdbaRNaQIdxa8RNaQIdKMg8Pa8PMMaRNaQId8KMMMh8Nava8AaD2cdtfhLawadaD2cltfhsaQIdyh8UaDhQinaLIdbg8PJbbb;aNascxfIdbaIascwfIdbNaRasIdbNa8RasclfIdbNMMMNa8Pa8PNa8UNa8NMMh8NaLclfhLasczfhsaQcufgQmbkaoaifgQIdwa8SNaQIdza8MNaQIdaMg8Pa8PMMa8SNaQIdlayNaQIdCa8SNaQId3Mg8Pa8PMMayNaQIdba8MNaQIdxayNaQIdKMg8Pa8PMMa8MNaQId8KMMMhIavaYaD2cdtfhLawa8KaD2cltfhsaQIdyhRaDhQinaLIdbg8PJbbb;aNascxfIdba8SascwfIdbNa8MasIdbNayasclfIdbNMMMNa8Pa8PNaRNaIMMhIaLclfhLasczfhsaQcufgQmbka8WaI:lMh8Wa8Xa8N:lMh8Xkaga8AaYa8Xa8W9FgsEBdba3a5aKasEBdbaOa8Xa8WasEUdbaecefgeaz9hmbkaPc;Wbfcbcj;abz:ljjjb8Aa9chsazhLinaPc;WbfasydbcO4c;8ZGfgQaQydbcefBdbascxfhsaLcufgLmbkcbhscbhLinaPc;WbfasfgQydbh3aQaLBdba3aLfhLasclfgscj;ab9hmbkcbhsa9chLinaPc;WbfaLydbcO4c;8ZGfgQaQydbgQcefBdbaxaQcdtfasBdbaLcxfhLazascefgs9hmbkahaq9RgQci9UhJdnalTmbcbhsaHhLinaLasBdbaLclfhLalascefgs9hmbkkcbh9eancbalz:ljjjbhTaQcO9UhSaJce4h9haPydlh9icbhicbhgdnina8Laxagcdtfydbcx2fgOIdwg8Na8V9EmeaiaJ9pmeJFFuuh8Pdna9haz9pmba8Laxa9hcdtfydbcx2fIdwJbb;aZNh8Pkdna8Na8P9ETmbaiaS0mdkdnaTaCaOydlg6cdtg9kfydbg3fg0RbbaTaCaOydbgKcdtg9mfydbg9nfg9oRbbVmbdnaZa9ncdtfgsclfydbgLasydbgsSmbaLas9Rh5a9iascitfhsa8Ja3cx2fgYcwfhdaYclfhAa8Ja9ncx2fg8Kcwfh9pa8Kclfh9qcbhLcehednindnaHasydbcdtfydbgQa3SmbaHasclfydbcdtfydbg8Aa3SmbaQa8ASmba8Ja8Acx2fg8AIdba8JaQcx2fgQIdbgI:tg8Pa9qIdbaQIdlg8S:tg8MNa8KIdbaI:tgya8AIdla8S:tg8NN:ta8PaAIdba8S:tgRNaYIdbaI:tg8Ra8NN:tNa8Na9pIdbaQIdwg8S:tg8UNa8Ma8AIdwa8S:tgIN:ta8NadIdba8S:tg8SNaRaIN:tNaIayNa8Ua8PN:taIa8RNa8Sa8PN:tNMMJbbbb9FmdkascwfhsaLcefgLa56hea5aL9hmbkkaeceGTmba9hcefh9hxeka8Ea3c8S2gQfgsa8Ea9nc8S2g8AfgLIdbasIdbMUdbasaLIdlasIdlMUdlasaLIdwasIdwMUdwasaLIdxasIdxMUdxasaLIdzasIdzMUdzasaLIdCasIdCMUdCasaLIdKasIdKMUdKasaLId3asId3MUd3asaLIdaasIdaMUdaasaLId8KasId8KMUd8KasaLIdyasIdyMUdydnaDTmbaoaQfgsaoa8AfgLIdbasIdbMUdbasaLIdlasIdlMUdlasaLIdwasIdwMUdwasaLIdxasIdxMUdxasaLIdzasIdzMUdzasaLIdCasIdCMUdCasaLIdKasIdKMUdKasaLId3asId3MUd3asaLIdaasIdaMUdaasaLId8KasId8KMUd8KasaLIdyasIdyMUdyaca9n2heaca32hYawhLaDh8AinaLaYfgsaLaefgQIdbasIdbMUdbasclfg5aQclfIdba5IdbMUdbascwfg5aQcwfIdba5IdbMUdbascxfgsaQcxfIdbasIdbMUdbaLczfhLa8Acufg8AmbkkaOcwfhLdndndndnaEaKfgQRbbc9:fPdebdkaKhsinaHascdtgsfa3BdbaXasfydbgsaK9hmbxikkaXa9kfydbhsaXa9mfydbhKaHa9mfa6Bdbash6kaHaKcdtfa6Bdbka9oce86bba0ce86bbaLIdbg8Pa8Ya8Ya8P9DEh8Ya9ecefh9ececdaQRbbceSEaifhikagcefggaz9hmbkkdna9embahhdxikdnalTmbcbhLa8FhsindnasydbgQcuSmbdnaLaHaQcdtg3fydbgQ9hmba8Fa3fydbhQkasaQBdbkasclfhsalaLcefgL9hmbkcbhLaahsindnasydbgQcuSmbdnaLaHaQcdtg3fydbgQ9hmbaaa3fydbhQkasaQBdbkasclfhsalaLcefgL9hmbkkcbhdabhscbh8AindnaHasydbcdtfydbgLaHasclfydbcdtfydbgQSmbaLaHascwfydbcdtfydbg3SmbaQa3Smbabadcdtfg5aLBdba5clfaQBdba5cwfa3Bdbadcifhdkascxfhsa8Acifg8Aah6mbkadaq9nmdxbkkaPabadalaCz:cjjjbkdnamTmbama8Y:rUdbkaPyd9OgscdtaPcwffc98fhCdninasTmeaCydbcbyd:m:jjjbH:bjjjbbaCc98fhCascufhsxbkkaPc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8KbabaeadaialavcbcbcbcbaoarawaDz:bjjjbk8KbabaeadaialavaoarawaDaqakaxamz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; + var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;H9Usdbk;N6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascwfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd1:jjjbHjjjjbbgHBdwasceBd9OasaHBdbascuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgOBdxascdBd9OasaOBdlasaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd1:jjjbHjjjjbbgXBdzasciBd9OasaCcbyd1:jjjbHjjjjbbgQBdCasclBd9Oalcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd1:jjjbHjjjjbbgLBdKascvBd9OaLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd:m:jjjbH:bjjjbbasclBd9Oasalcbyd1:jjjbHjjjjbbg3BdKascvBd9OasaCcbyd1:jjjbHjjjjbbgzBd3ascoBd9OasaCcbyd1:jjjbHjjjjbbgKBdaascrBd9OazcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Kascwfasyd9Ogzcdtfa8KBdbasazcefgABd9Oa8Kaialavz:djjjbdndnaDmbcbhvxekcbh8EascwfaAcdtfcuaDal2gKcdtaKcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbasazcdfgABd9OalTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascwfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd1:jjjbHjjjjbbgKBdbasaAcefg5Bd9OaKcbazz:ljjjbh8FdndndnaDTmbascwfa5cdtfaLcbyd1:jjjbHjjjjbbgoBdbasaAcdfgKBd9Oaocbazz:ljjjb8AascwfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd1:jjjbHjjjjbbgqBdbasaAcifBd9OaqcbaKz:ljjjb8AadmexdkcbhocbhqadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Eaeh8AincbhKina3aeaKc:G1jjbfydba8EfcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:W1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekJbbacJbbjZazceSEh8RaEceShAa8KaeaKc:K1jjbfydba8Efcdtfydbcx2fhzdna8KaLcx2fgEIdwa8Ka5cx2fgYIdwg8P:tgIaINaEIdbaYIdbg8U:tgyayNaEIdlaYIdlg8S:tgRaRNMM:rg8NJbbbb9ETmbaIa8N:vhIaRa8N:vhRaya8N:vhykJbbaca8RaAEh8XdnazIdwa8P:tg8RaIa8RaINazIdba8U:tg8YayNaRazIdla8S:tg8WNMMg8VN:tg8Ra8RNa8Yaya8VN:tgIaINa8WaRa8VN:tgyayNMM:rgRJbbbb9ETmba8RaR:vh8RayaR:vhyaIaR:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNgRaINNg8VazIdbMUdbazayaRayNg8XNg8YazIdlMUdlaza8RaRa8RNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIaRa8Ra8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3aza8Ra8NNg8RazIdaMUdaaza8Na8PNg8NazId8KMUd8KazaRazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3aza8RazIdaMUdaaza8NazId8KMUd8KazaRazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Ecifg8Ead6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tg8Ra8RNaKIdlaLIdlg80:tgRaRNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNa8RazIdba8Z:tg8PNaRazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNaRaIN:ta8VNh83a8YaRNa8SaIN:ta8VNhUa8Xa8PNa8RaIN:ta8VNh85a8Ya8RNa8PaIN:ta8VNh86a8Ra8SNa8PaRN:tgIaINaRa8NNa8SayN:tgIaINaya8PNa8Na8RN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tgRNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUaRNa83a8PNMg8RNUdbazaIa86aRNa85a8PNMgRNUdbazcxfaIa87ayNa88a8RNa8Na89aRNMMMg8NNUdbaIaya8RNNa8YMh8YaIayaRNNa8WMh8WaIa8RaRNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIa8Ra8NNNa8VMh8VaIaRa8NNNa8XMh8XaIayayNNa80Mh80aIa8Ra8RNNa8:Mh8:aIaRaRNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaoaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydbhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Mascwfasyd9Ogzcdtfa8MBdbasazcefgKBd9OascwfaKcdtfcuamcdtamcFFFFi0Ecbyd1:jjjbHjjjjbbgwBdbasazcdfgKBd9OascwfaKcdtfaCcbyd1:jjjbHjjjjbbgOBdbasazcifgKBd9OascwfaKcdtfalcbyd1:jjjbHjjjjbbgcBdbasazclfBd9OJbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasabadggalaXz:cjjjbabhAcbhHcbhYincbhzindnaXaAazfydbgLcdtg8AfydbgEaXabazc;m1jjbfydbaYfcdtfydbgKcdtfydbg8ESmba3aKfRbbgecv2a3aLfRbbg5fc;G1jjbfRbbg8La5cv2aefg8Jc;G1jjbfRbbgiVcFeGTmbdna8Jc:W1jjbfRbbTmba8EaE0mekdna5ae9hmba5cufcFeGce0mbaaa8AfydbaK9hmeka8MaHcx2fg5aKaLaicFeGgEEBdla5aLaKaEEBdba5aEa8LGcb9hBdwaHcefhHkazclfgzcx9hmbkdnaYcifgYag9pmbaAcxfhAaHcifam9nmekkdnaHmbaghdxikcbheinJbbbbJbbjZa8FaXa8Maecx2fg5ydlgEa5ydbg8Ea5ydwgKEgYcdtfydbg8Lc8S2gifgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEg8Acx2fgKIdwgRNazIdzaKIdbg8NNazIdaMgIaIMMaRNazIdlaKIdlg8PNazIdCaRNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbgdc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwg8RNazIdzaKIdbg8UNazIdaMgIaIMMa8RNazIdlaKIdlg8SNazIdCa8RNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfhAa5clfh8JdnaDTmbaoaLfgLIdwa8RNaLIdza8UNaLIdaMgIaIMMa8RNaLIdla8SNaLIdCa8RNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKaqadaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaoaifgLIdwaRNaLIdza8NNaLIdaMgIaIMMaRNaLIdla8PNaLIdCaRNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMh8Rava8AaD2cdtfhKaqa8LaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNa8RMMh8RaKclfhKazczfhzaLcufgLmbka8Xa8R:lMh8Xa8Yay:lMh8Yka8JaEa8Aa8Ya8X9FgzEBdba5a8EaYazEBdbaAa8Ya8XazEUdbaecefgeaH9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzaHhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbawaLcdtfazBdbaKcxfhKaHazcefgz9hmbkagak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydlh6cbhicbh8Jdnina8Mawa8Jcdtfydbcx2fgAIdwgya8W9Emeaia9e9pmeJFFuuhIdna9iaH9pmba8Mawa9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaia9h0mdkdnaSaXaAydlg9kcdtg0fydbg5fg9mRbbaSaXaAydbgYcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fg8Acwfhda8AclfhCa8Ka9ocx2fg8Lcwfhra8Lclfh9qcbhKcehednindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbg8R:tgIa9qIdbaLIdlgR:tg8NNa8LIdba8R:tg8PaEIdlaR:tgyN:taIaCIdbaR:tg8UNa8AIdba8R:tg8SayN:tNayarIdbaLIdwgR:tg8VNa8NaEIdwaR:tg8RN:tayadIdbaR:tgRNa8Ua8RN:tNa8Ra8PNa8VaIN:ta8Ra8SNaRaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6hea8EaK9hmbkkaeceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaoaLfgzaoaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2hea9ca52h8AaqhKaDhEinaKa8AfgzaKaefgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkkaAcwfhKdndndndna3aYfgLRbbc9:fPdebdkaYhzinaOazcdtgzfa5BdbaQazfydbgzaY9hmbxikkaQa0fydbhzaQa9nfydbhYaOa9nfa9kBdbazh9kkaOaYcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaifhika8Jcefg8JaH9hmbkkdnaTmbaghdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8EclfaLBdba8Ecwfa5BdbadcifhdkazcxfhzaEcifgEag6mbkadak9nmdxbkkasabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd9Ogzcdtascwffc98fhXdninazTmeaXydbcbyd:m:jjjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; - var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); + var wasmpack = new Uint8Array([32, 0, 65, 2, 1, 106, 34, 33, 3, 128, 11, 4, 13, 64, 6, 253, 10, 7, 15, 116, 127, 5, 8, 12, 40, 16, 19, 54, 20, 9, 27, 255, 113, 17, 42, 67, 24, 23, 146, 148, 18, 14, 22, 45, 70, 69, 56, 114, 101, 21, 25, 63, 75, 136, 108, 28, 118, 29, 73, 115]); if (typeof WebAssembly !== 'object') { return { @@ -17,10 +17,10 @@ var MeshoptSimplifier = (function() { var ready = WebAssembly.instantiate(unpack(wasm), {}) - .then(function(result) { - instance = result.instance; - instance.exports.__wasm_call_ctors(); - }); + .then(function (result) { + instance = result.instance; + instance.exports.__wasm_call_ctors(); + }); function unpack(data) { var result = new Uint8Array(data.length); @@ -95,7 +95,7 @@ var MeshoptSimplifier = (function() { return [target, error[0]]; } - function simplifyAttr(fun, indices, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, target_index_count, target_error, options) { + function simplifyAttr(fun, indices, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, options) { var sbrk = instance.exports.sbrk; var te = sbrk(4); var ti = sbrk(index_count * 4); @@ -103,12 +103,15 @@ var MeshoptSimplifier = (function() { var sa = sbrk(vertex_count * vertex_attributes_stride); var sw = sbrk(attribute_weights.length * 4); var si = sbrk(index_count * 4); + var vl = vertex_lock && sbrk(vertex_count); var heap = new Uint8Array(instance.exports.memory.buffer); heap.set(bytes(vertex_positions), sp); heap.set(bytes(vertex_attributes), sa); heap.set(bytes(attribute_weights), sw); heap.set(bytes(indices), si); - var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, sa, vertex_attributes_stride, sw, attribute_weights.length, target_index_count, target_error, options, te); + if (vertex_lock) + heap.set(bytes(vertex_lock), vl); + var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, sa, vertex_attributes_stride, sw, attribute_weights.length, vl, target_index_count, target_error, options, te); // heap may have grown heap = new Uint8Array(instance.exports.memory.buffer); var target = new Uint32Array(result); @@ -160,7 +163,7 @@ var MeshoptSimplifier = (function() { // note that these functions are experimental and may change interface/behavior in a way that will require revising calling code useExperimentalFeatures: false, - compactMesh: function(indices) { + compactMesh: function (indices) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -168,7 +171,7 @@ var MeshoptSimplifier = (function() { return reorder(instance.exports.meshopt_optimizeVertexFetchRemap, indices32, maxindex(indices) + 1); }, - simplify: function(indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { + simplify: function (indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); assert(vertex_positions instanceof Float32Array); @@ -190,7 +193,7 @@ var MeshoptSimplifier = (function() { return result; }, - simplifyWithAttributes: function(indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, target_index_count, target_error, flags) { + simplifyWithAttributes: function (indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, flags) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -200,6 +203,7 @@ var MeshoptSimplifier = (function() { assert(vertex_attributes instanceof Float32Array); assert(vertex_attributes.length % vertex_attributes_stride == 0); assert(vertex_attributes_stride >= 0); + assert(vertex_lock == null || vertex_lock.length == vertex_positions.length); assert(target_index_count >= 0 && target_index_count <= indices.length); assert(target_index_count % 3 == 0); assert(target_error >= 0 && target_error <= 1); @@ -212,21 +216,24 @@ var MeshoptSimplifier = (function() { options |= simplifyOptions[flags[i]]; } + if (vertex_lock) + vertex_lock = new Uint8Array(vertex_lock); + var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices); - var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), target_index_count, target_error, options); + var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), vertex_lock, target_index_count, target_error, options); result[0] = (indices instanceof Uint32Array) ? result[0] : new indices.constructor(result[0]); return result; }, - getScale: function(vertex_positions, vertex_positions_stride) { + getScale: function (vertex_positions, vertex_positions_stride) { assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); assert(vertex_positions_stride >= 3); return simplifyScale(instance.exports.meshopt_simplifyScale, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4); }, - simplifyPoints: function(vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { + simplifyPoints: function (vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); diff --git a/js/meshopt_simplifier.test.js b/js/meshopt_simplifier.test.js index 8e89af4aef..570d294df8 100644 --- a/js/meshopt_simplifier.test.js +++ b/js/meshopt_simplifier.test.js @@ -164,7 +164,7 @@ var tests = { var attr_weights = [0.01, 0.01, 0.01]; - var res = simplifier.simplifyWithAttributes(ib, vb_pos, 3, vb_att, 3, attr_weights, 6 * 3, 1e-2); + var res = simplifier.simplifyWithAttributes(ib, vb_pos, 3, vb_att, 3, attr_weights, null, 6 * 3, 1e-2); var expected = new Uint32Array([ 0, 2, 9, 9, 2, 11, diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index 6ab48c1968..722ecb0c36 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -357,9 +357,10 @@ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsig * vertex_attributes should have attribute_count floats for each vertex * attribute_weights should have attribute_count floats in total; the weights determine relative priority of attributes between each other and wrt position. The recommended weight range is [1e-3..1e-1], assuming attribute data is in [0..1] range. * attribute_count must be <= 16 + * vertex_lock can be NULL; when not NULL, it should have vertex_count chars, 1 for each vertex; they determine which vertices are locked (1) or free to be simplified (0). * TODO target_error/result_error currently use combined distance+attribute error; this may change in the future */ -MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* result_error); +MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error); /** * Experimental: Mesh simplifier (sloppy) @@ -659,7 +660,7 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const template inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL); template -inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL); +inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL); template inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = NULL); template @@ -966,12 +967,12 @@ inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_co } template -inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* result_error) +inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error) { meshopt_IndexAdapter in(NULL, indices, index_count); meshopt_IndexAdapter out(destination, NULL, index_count); - return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, target_index_count, target_error, options, result_error); + return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, result_error); } template diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 4073bb4dc7..a84b33270a 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -252,7 +252,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int return false; } -static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, unsigned int options) +static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_lock, unsigned int options) { memset(loop, -1, vertex_count * sizeof(unsigned int)); memset(loopback, -1, vertex_count * sizeof(unsigned int)); @@ -298,7 +298,12 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned { if (remap[i] == i) { - if (wedge[i] == i) + if (vertex_lock && vertex_lock[i]) + { + // vertex is explicitly locked + result[i] = Kind_Locked; + } + else if (wedge[i] == i) { // no attribute seam, need to check if it's manifold unsigned int openi = openinc[i], openo = openout[i]; @@ -1468,7 +1473,7 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = NULL; MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = NULL; #endif -size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) +size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { using namespace meshopt; @@ -1499,7 +1504,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic unsigned char* vertex_kind = allocator.allocate(vertex_count); unsigned int* loop = allocator.allocate(vertex_count); unsigned int* loopback = allocator.allocate(vertex_count); - classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, options); + classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, vertex_lock, options); #if TRACE size_t unique_positions = 0; @@ -1634,12 +1639,12 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { - return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, target_index_count, target_error, options, out_result_error); + return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, NULL, target_index_count, target_error, options, out_result_error); } -size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) +size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { - return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, vertex_attributes_data, vertex_attributes_stride, attribute_weights, attribute_count, target_index_count, target_error, options, out_result_error); + return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, vertex_attributes_data, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, out_result_error); } size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) From 1c91990ed5b3d731230210b992001978868d156b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Apr 2024 16:33:53 -0700 Subject: [PATCH 043/581] js: Update meshopt_encoder Wasm binaries These were not rebuilt after vcacheoptimizer tweaks. --- js/meshopt_encoder.js | 2 +- js/meshopt_encoder.module.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/meshopt_encoder.js b/js/meshopt_encoder.js index e092cb5994..221da355bf 100644 --- a/js/meshopt_encoder.js +++ b/js/meshopt_encoder.js @@ -4,7 +4,7 @@ var MeshoptEncoder = (function() { "use strict"; // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 - var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:W;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq:g9sLdbk;3keYu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRb:S:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9UhodndndndndnalTmbaoc;WFbGgecjdaecjd6Ehqcbhkdninakai9pmiaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndndndnaec9WGgsTmbcbhzcehHaPhOawhAxekdnaxTmbcbhAcehHaPhCinaDaAfRbbhXaDcjlfheaChoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkaraw9Ram6miawcbamzNjjjbgeTmiaCcefhCaeamfhwaAcefgAal6hHaAal9hmbxvkkaraw9Ram6mvawcbamzNjjjb8AceheinawgXamfhwalaegoSmldnaraw9Ram6mbaocefheawcbamzNjjjb8AaXmekkaoal6hHxekindnaxTmbaDazfRbbhXaDcjlfheaOhoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkkaraA9Ram6mearaAcbamzNjjjbgKamfgw9RcK6mdcbhYaDcjlfhAinaDcjlfaYfh8AcwhCczhLcehQindndnaQce9hmbcuhoa8ARbbmecbhodninaogecsSmeaecefhoaAaefcefRbbTmbkkcucbaecs6EhoxekaQcetc;:FFFeGhocuaQtcu7cFeGhXcbheinaoaXaAaefRbb9nfhoaecefgecz9hmbkkaoaLaoaL6geEhLaQaCaeEhCaQcetgQcw6mbkdndndndnaCcufPdiebkaKaYco4fgeaeRbbcdciaCclSEaYci4coGtV86bbaCcw9hmeawa8A8Pbb83bbawcwfa8Acwf8Pbb83bbawczfhwxdkaKaYco4fgeaeRbbceaYci4coGtV86bbkdncwaC9TgEmbinawcb86bbawcefhwxbkkcuaCtcu7h8Acbh3aAh5ina5heaEhQcbhoinaeRbbgLa8AcFeGgXaLaX6EaoaCtVhoaecefheaQcufgQmbkawao86bba5aEfh5awcefhwa3aEfg3cz6mbkcbheindnaAaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaYczfgYas9pmbaAczfhAaraw9RcL0mekkaYas6meawTmeaOcefhOazcefgzal6hHawhAazalSmixbkkcbhwaHceGTmexikcbhwaHceGmdkaDaPaxcufal2falz:tjjjb8AaxakfhkawmbkcbhoxokcbhoxvkaiTmekcbhoaraw9Ralcaalca0E6mialc8F9nmexdkcbhoaecufca6mdkawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9Rhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBd:S:kjjbk;rse3u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:C:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgoydbhLaocwfydbhKaoclfydbhYcbh8Adndninalc;abfavcsGcitfgoydlhEdndndnaoydbgoaL9hmbaEaYSmekdnaoaY9hmbaEaK9hmba8Acefh8AxekaoaK9hmeaEaL9hmea8Acdfh8Aka8Ac870mdaXcufhvada8AciGcx2goc:y1jjbfydbaCfcdtfydbhEadaocN1jjbfydbaCfcdtfydbhKadaoc:q1jjbfydbaCfcdtfydbhLcbhodnindnalavcsGcdtfydbaE9hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaEaOSgvaYce9iaYaH9oVgoGh3dndndndndncbcsavEaYaoEgvcs9hmbarce9imbaEaEaAaEcefaASgvEgAcefSmecmcsavEhvkasava8Acdtc;WeGV86bbavcs9hmeaEaA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbkaEhAxdkcPhvasa8AcdtcPV86bbaEhAkavTmbavaH9imekalaXcdtfaEBdbaXcefcsGhXkaOa3fhOalc;abfaQcitfgvaKBdlavaEBdbalc;abfaQcefcsGgvcitfgoaEBdlaoaLBdbavcefhoxikavcufhva8Aclfg8Ac;ab9hmbkkdnadceaKaOScetaYaOSEcx2gvc:q1jjbfydbaCfcdtfydbgLTadavcN1jjbfydbaCfcdtfydbg8AceSGadavc:y1jjbfydbaCfcdtfydbgYcdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhKxdkcuhKaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydbaY9hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaLaOSg8Efh3dndnaKcm0mbaKcefhKxekcbcsa8Aa3SgvEhKa3avfh3kdndnaEcm0mbaEcefhExekcbcsaYa3SgvEhEa3avfh3kc9:cua8EEh8FaEaKcltVhocbhvdndndninavcj1jjbfRbbaocFeGSmeavcefgvcz9hmbxdkka5aLaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeao86bbaecefhekdna8EmbaLaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaLhAkdnaKcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmbaYaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaYhAkalaXcdtfaLBdbaXcefcsGhvdndnaKPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfaYBdbavcefcsGhvkalc;abfaQcitfgoaLBdlaoa8ABdbalc;abfaQcefcsGcitfgoa8ABdlaoaYBdbalc;abfaQcdfcsGcitfgoaYBdlaoaLBdbaQcifhoavhXa3hOkascefhsaocsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:C:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:C:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:dvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhralcxfIdbhqdndnakJbbbb9GTmbaxhkxekJbbjZar:l:tgkak:maxJbbbb9GEhkJbbjZax:l:tgxax:marJbbbb9GEhrkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEavNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohmxekcjjjj94hmkdndnakJbbj:;akJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;akJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;klld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicdfciGcdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:Hvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6mearcearce0EhwaohDinaDc:CuBdbaDclfhDawcufgwmbkaeTmiadcl6mdarcearce0EhqarcdthkalhxcbhminaohDaxhwaqhPinaDaDydbgsawydbgzcL4cFeGc:cufcbazEgzasaz9kEBdbawclfhwaDclfhDaPcufgPmbkaxakfhxamcefgmae9hmbkkaeTmdxekaeTmekavcb9hadcl6gqVhHarcearce0Ehkarcdthrceai9Rhmcbhdindndndnavce9hmbaqmdc:CuhwalhDakhPinawaDydbgscL4cFeGc:cufcbasEgsawas9kEhwaDclfhDaPcufgPmbxdkkc:CuhwaHmbaohDalhPakhsinaDaPydbgzcL4cFeGgxc8Aaxc8A9kEc:cufcbazEBdbaPclfhPaDclfhDascufgsmbkkaqmbcbhDakhsinawhPdnavceSmbaoaDfydbhPkdndnalaDfIdbgOcjjj;8iamaPfgPcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohzxekcjjjj94hzkabaDfazcFFFrGaPcKtVBdbaDclfhDascufgsmbkkabarfhbalarfhladcefgdae9hmbkkaocjdf8KjjjjbkFkdCui998Jjjjjbc:Gd9Rgv8Kjjjjbavc:4efcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgoadcFFFFi0Ecbyd:K:kjjbHjjjjbbgeBd:4eavceBd:ydaeabaoz:tjjjb8Akavc:OefcwfcbBdbav9cb83i:Oeavc:Oefaeadaiavc:4efz:njjjbcuaicdtgraicFFFFi0Egwcbyd:K:kjjbHjjjjbbhoavc:4efavyd:ydgDcdtfaoBdbavaDcefgqBd:ydaoavyd:Oegkarz:tjjjbhxavc:4efaqcdtfadci9Ugmcbyd:K:kjjbHjjjjbbgoBdbavaDcdfgrBd:ydaocbamzNjjjbhPavc:4efarcdtfawcbyd:K:kjjbHjjjjbbgsBdbavaDcifgqBd:ydaxhoashrinaralIdbalaoydbgwcwawcw6Ecdtfc;ebfIdbMUdbaoclfhoarclfhraicufgimbkavc:4efaqcdtfcuamcdtadcFFFF970Ecbyd:K:kjjbHjjjjbbgqBdbavaDclfBd:yddnadci6mbamceamce0EhiaehoaqhrinarasaoydbcdtfIdbasaoclfydbcdtfIdbMasaocwfydbcdtfIdbMUdbaocxfhoarclfhraicufgimbkkavc;qbfhzavhoavyd:SehHavyd:WehOcbhwcbhrcbhAcehCinaohXcihQaearci2gLcdtfgocwfydbhdaoydbhDabaAcx2fgiclfaoclfydbgKBdbaiaDBdbaicwfadBdbaParfce86bbazadBdwazaKBdlazaDBdbaqarcdtfcbBdbdnawTmbcihQaXhiinazaQcdtfaiydbgoBdbaQaoaD9haoaK9hGaoad9hGfhQaiclfhiawcufgwmbkkaAcefhAaxaDcdtfgoaoydbcufBdbaxaKcdtfgoaoydbcufBdbaxadcdtfgoaoydbcufBdbcbhwinaOaHaeawaLfcdtfydbcdtgifydbcdtfgKhoakaifgDydbgdhidnadTmbdninaoydbarSmeaoclfhoaicufgiTmdxbkkaoadcdtaKfc98fydbBdbaDaDydbcufBdbkawcefgwci9hmbkdndndnaQTmbcuhrJbbbbhYcbhDavyd:SehKavyd:WehLindndnakazaDcdtfydbcdtgofydbgimbaDcefhDxekaDcs0hwasaofgdIdbh8AadalcbaDcefgDawEcdtfIdbalaxaofydbgwcwawcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEaicdthiaLaKaofydbcdtfhoinaqaoydbgwcdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYawaradEhraoclfhoaic98fgimbkkaDaQ9hmbkarcu9hmekaCam9pmeindnaPaCfRbbmbaChrxdkamaCcefgC9hmbxdkkaQczaQcz6EhwazhoaXhzarcu9hmekkavyd:ydhokaocdtavc:4effc98fhrdninaoTmearydbcbyd:G:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:Gdf8Kjjjjbk;UlevucuaicdtgvaicFFFFi0Egocbyd:K:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhwdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbawceawce0EhDabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;:kivuo99lu8Jjjjjbcj;Hb9Rgl8Kjjjjbcbhvalc1;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:K:kjjbHjjjjbbgrBd19GalceBd;O9Galcwfcbyd:m:kjjbBdbalcb8Pd:e:kjjb83ibalc;W;Gbfcwfcbyd:y:kjjbBdbalcb8Pd:q:kjjb83i;W9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;W;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;49GhDalIdlhkalId;09GhxalIdbhmalId;W9GhPkdndnadTmbJbbbbJbbjZaPam:tJbbbb:xgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhialaocbyd:K:kjjbHjjjjbbgzBd:m9GdnadTmbabhHinaHaiBdbaHclfhHadaicefgi9hmbkadTmbabhiadhHinalaraiydbgecdtfydbcFrGcx2fgvavydbgvcefBdbazavcdtfaeBdbaiclfhiaHcufgHmbkazhiadhHinalaraiydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaiclfhiaHcufgHmbkabhiadhHinalaraiydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwazavcdtfaeBdbaiclfhiaHcufgHmbkadTmbcbhiinabazydbcdtfaiBdbazclfhzadaicefgi9hmbkkclhidninaic98Smealc1;Gbfaifydbcbyd:G:kjjbH:bjjjbbaic98fhixbkkalcj;Hbf8Kjjjjbk9teiucbcbyd:O:kjjbgeabcifc98GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:O:kjjbgeabcrfc94GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:O:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:O:kjjbfgdBd:O:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:6ddbcjwk:Cdb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:FFuuFFuuFFuuFFuFFFuFFFuFbc:Cqkzebbbebbbdbbb8WWbb"; + var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:W;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXqF9qLdbk;3keYu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRb:S:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9UhodndndndndnalTmbaoc;WFbGgecjdaecjd6Ehqcbhkdninakai9pmiaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndndndnaec9WGgsTmbcbhzcehHaPhOawhAxekdnaxTmbcbhAcehHaPhCinaDaAfRbbhXaDcjlfheaChoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkaraw9Ram6miawcbamzNjjjbgeTmiaCcefhCaeamfhwaAcefgAal6hHaAal9hmbxvkkaraw9Ram6mvawcbamzNjjjb8AceheinawgXamfhwalaegoSmldnaraw9Ram6mbaocefheawcbamzNjjjb8AaXmekkaoal6hHxekindnaxTmbaDazfRbbhXaDcjlfheaOhoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkkaraA9Ram6mearaAcbamzNjjjbgKamfgw9RcK6mdcbhYaDcjlfhAinaDcjlfaYfh8AcwhCczhLcehQindndnaQce9hmbcuhoa8ARbbmecbhodninaogecsSmeaecefhoaAaefcefRbbTmbkkcucbaecs6EhoxekaQcetc;:FFFeGhocuaQtcu7cFeGhXcbheinaoaXaAaefRbb9nfhoaecefgecz9hmbkkaoaLaoaL6geEhLaQaCaeEhCaQcetgQcw6mbkdndndndnaCcufPdiebkaKaYco4fgeaeRbbcdciaCclSEaYci4coGtV86bbaCcw9hmeawa8A8Pbb83bbawcwfa8Acwf8Pbb83bbawczfhwxdkaKaYco4fgeaeRbbceaYci4coGtV86bbkdncwaC9TgEmbinawcb86bbawcefhwxbkkcuaCtcu7h8Acbh3aAh5ina5heaEhQcbhoinaeRbbgLa8AcFeGgXaLaX6EaoaCtVhoaecefheaQcufgQmbkawao86bba5aEfh5awcefhwa3aEfg3cz6mbkcbheindnaAaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaYczfgYas9pmbaAczfhAaraw9RcL0mekkaYas6meawTmeaOcefhOazcefgzal6hHawhAazalSmixbkkcbhwaHceGTmexikcbhwaHceGmdkaDaPaxcufal2falz:tjjjb8AaxakfhkawmbkcbhoxokcbhoxvkaiTmekcbhoaraw9Ralcaalca0E6mialc8F9nmexdkcbhoaecufca6mdkawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9Rhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBd:S:kjjbk;rse3u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:C:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgoydbhLaocwfydbhKaoclfydbhYcbh8Adndninalc;abfavcsGcitfgoydlhEdndndnaoydbgoaL9hmbaEaYSmekdnaoaY9hmbaEaK9hmba8Acefh8AxekaoaK9hmeaEaL9hmea8Acdfh8Aka8Ac870mdaXcufhvada8AciGcx2goc:y1jjbfydbaCfcdtfydbhEadaocN1jjbfydbaCfcdtfydbhKadaoc:q1jjbfydbaCfcdtfydbhLcbhodnindnalavcsGcdtfydbaE9hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaEaOSgvaYce9iaYaH9oVgoGh3dndndndndncbcsavEaYaoEgvcs9hmbarce9imbaEaEaAaEcefaASgvEgAcefSmecmcsavEhvkasava8Acdtc;WeGV86bbavcs9hmeaEaA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbkaEhAxdkcPhvasa8AcdtcPV86bbaEhAkavTmbavaH9imekalaXcdtfaEBdbaXcefcsGhXkaOa3fhOalc;abfaQcitfgvaKBdlavaEBdbalc;abfaQcefcsGgvcitfgoaEBdlaoaLBdbavcefhoxikavcufhva8Aclfg8Ac;ab9hmbkkdnadceaKaOScetaYaOSEcx2gvc:q1jjbfydbaCfcdtfydbgLTadavcN1jjbfydbaCfcdtfydbg8AceSGadavc:y1jjbfydbaCfcdtfydbgYcdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhKxdkcuhKaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydbaY9hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaLaOSg8Efh3dndnaKcm0mbaKcefhKxekcbcsa8Aa3SgvEhKa3avfh3kdndnaEcm0mbaEcefhExekcbcsaYa3SgvEhEa3avfh3kc9:cua8EEh8FaEaKcltVhocbhvdndndninavcj1jjbfRbbaocFeGSmeavcefgvcz9hmbxdkka5aLaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeao86bbaecefhekdna8EmbaLaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaLhAkdnaKcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmbaYaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaYhAkalaXcdtfaLBdbaXcefcsGhvdndnaKPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfaYBdbavcefcsGhvkalc;abfaQcitfgoaLBdlaoa8ABdbalc;abfaQcefcsGcitfgoa8ABdlaoaYBdbalc;abfaQcdfcsGcitfgoaYBdlaoaLBdbaQcifhoavhXa3hOkascefhsaocsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:C:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:C:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:dvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhralcxfIdbhqdndnakJbbbb9GTmbaxhkxekJbbjZar:l:tgkak:maxJbbbb9GEhkJbbjZax:l:tgxax:marJbbbb9GEhrkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEavNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohmxekcjjjj94hmkdndnakJbbj:;akJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;akJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;klld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicdfciGcdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:Hvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6mearcearce0EhwaohDinaDc:CuBdbaDclfhDawcufgwmbkaeTmiadcl6mdarcearce0EhqarcdthkalhxcbhminaohDaxhwaqhPinaDaDydbgsawydbgzcL4cFeGc:cufcbazEgzasaz9kEBdbawclfhwaDclfhDaPcufgPmbkaxakfhxamcefgmae9hmbkkaeTmdxekaeTmekavcb9hadcl6gqVhHarcearce0Ehkarcdthrceai9Rhmcbhdindndndnavce9hmbaqmdc:CuhwalhDakhPinawaDydbgscL4cFeGc:cufcbasEgsawas9kEhwaDclfhDaPcufgPmbxdkkc:CuhwaHmbaohDalhPakhsinaDaPydbgzcL4cFeGgxc8Aaxc8A9kEc:cufcbazEBdbaPclfhPaDclfhDascufgsmbkkaqmbcbhDakhsinawhPdnavceSmbaoaDfydbhPkdndnalaDfIdbgOcjjj;8iamaPfgPcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohzxekcjjjj94hzkabaDfazcFFFrGaPcKtVBdbaDclfhDascufgsmbkkabarfhbalarfhladcefgdae9hmbkkaocjdf8Kjjjjbk;4qdAui998Jjjjjbc:Gd9Rgv8Kjjjjbavc:4efcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgoadcFFFFi0Ecbyd:K:kjjbHjjjjbbgeBd:4eavceBd:ydaeabaoz:tjjjb8Akavc:OefcwfcbBdbav9cb83i:Oeavc:Oefaeadaiavc:4efz:njjjbavyd:Oehradci9Ugwcbyd:K:kjjbHjjjjbbhoavc:4efavyd:ydgDcdtfaoBdbavaDcefgqBd:ydaocbawzNjjjbhkavc:4efaqcdtfcuaicdtaicFFFFi0Ecbyd:K:kjjbHjjjjbbgxBdbavaDcdfgmBd:ydarhoaxhqinaqalIdbalaoydbgPcwaPcw6Ecdtfc;ebfIdbMUdbaoclfhoaqclfhqaicufgimbkavc:4efamcdtfcuawcdtadcFFFF970Ecbyd:K:kjjbHjjjjbbgmBdbavaDcifBd:yddnadci6mbawceawce0EhiaehoamhqinaqaxaoydbcdtfIdbaxaoclfydbcdtfIdbMaxaocwfydbcdtfIdbMUdbaocxfhoaqclfhqaicufgimbkkavc;qbfhsavhoavyd:Sehzavyd:WehHcbhPcbhqcbhOcehAinaohCcihXaeaqci2gQcdtfgocwfydbhdaoydbhDabaOcx2fgiclfaoclfydbgLBdbaiaDBdbaicwfadBdbakaqfce86bbasadBdwasaLBdlasaDBdbamaqcdtfcbBdbdnaPTmbcihXaChiinasaXcdtfaiydbgoBdbaXaoad9haoaD9haoaL9hGGfhXaiclfhiaPcufgPmbkkaOcefhOcbhPinaHazaeaPaQfcdtfydbcdtgifydbcdtfgLhoaraifgDydbgdhidnadTmbdninaoydbaqSmeaoclfhoaicufgiTmdxbkkaoadcdtaLfc98fydbBdbaDaDydbcufBdbkaPcefgPci9hmbkdndndnaXTmbcuhqJbbbbhKcbhDavyd:SehLavyd:WehQindndnarasaDcdtfydbcdtgPfydbgombaDcefhDxekaDcs0hiaxaPfgdIdbhYadalcbaDcefgDaiEcdtfIdbalaocwaocw6Ecdtfc;ebfIdbMg8AUdba8AaY:th8AaocdthiaQaLaPfydbcdtfhoinamaoydbgPcdtfgda8AadIdbMgYUdbaYaKaKaY9DgdEhKaPaqadEhqaoclfhoaic98fgimbkkaDaX9hmbkaqcu9hmekaAaw9pmeindnakaAfRbbmbaAhqxdkawaAcefgA9hmbxdkkaXczaXcz6EhPashoaChsaqcu9hmekkavyd:ydhokaocdtavc:4effc98fhqdninaoTmeaqydbcbyd:G:kjjbH:bjjjbbaqc98fhqaocufhoxbkkavc:Gdf8Kjjjjbk;UlevucuaicdtgvaicFFFFi0Egocbyd:K:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhwdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbawceawce0EhDabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;:kivuo99lu8Jjjjjbcj;Hb9Rgl8Kjjjjbcbhvalc1;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:K:kjjbHjjjjbbgrBd19GalceBd;O9Galcwfcbyd:m:kjjbBdbalcb8Pd:e:kjjb83ibalc;W;Gbfcwfcbyd:y:kjjbBdbalcb8Pd:q:kjjb83i;W9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;W;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;49GhDalIdlhkalId;09GhxalIdbhmalId;W9GhPkdndnadTmbJbbbbJbbjZaPam:tJbbbb:xgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhialaocbyd:K:kjjbHjjjjbbgzBd:m9GdnadTmbabhHinaHaiBdbaHclfhHadaicefgi9hmbkadTmbabhiadhHinalaraiydbgecdtfydbcFrGcx2fgvavydbgvcefBdbazavcdtfaeBdbaiclfhiaHcufgHmbkazhiadhHinalaraiydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaiclfhiaHcufgHmbkabhiadhHinalaraiydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwazavcdtfaeBdbaiclfhiaHcufgHmbkadTmbcbhiinabazydbcdtfaiBdbazclfhzadaicefgi9hmbkkclhidninaic98Smealc1;Gbfaifydbcbyd:G:kjjbH:bjjjbbaic98fhixbkkalcj;Hbf8Kjjjjbk9teiucbcbyd:O:kjjbgeabcifc98GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:O:kjjbgeabcrfc94GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:O:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:O:kjjbfgdBd:O:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:6ddbcjwk:Cdb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:FFuuFFuuFFuuFFuFFFuFFFuFbc:Cqkzebbbebbbdbbb8WWbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_encoder.module.js b/js/meshopt_encoder.module.js index 4805e3e7c9..0ce51b959d 100644 --- a/js/meshopt_encoder.module.js +++ b/js/meshopt_encoder.module.js @@ -3,7 +3,7 @@ var MeshoptEncoder = (function() { // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 - var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:W;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq:g9sLdbk;3keYu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRb:S:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9UhodndndndndnalTmbaoc;WFbGgecjdaecjd6Ehqcbhkdninakai9pmiaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndndndnaec9WGgsTmbcbhzcehHaPhOawhAxekdnaxTmbcbhAcehHaPhCinaDaAfRbbhXaDcjlfheaChoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkaraw9Ram6miawcbamzNjjjbgeTmiaCcefhCaeamfhwaAcefgAal6hHaAal9hmbxvkkaraw9Ram6mvawcbamzNjjjb8AceheinawgXamfhwalaegoSmldnaraw9Ram6mbaocefheawcbamzNjjjb8AaXmekkaoal6hHxekindnaxTmbaDazfRbbhXaDcjlfheaOhoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkkaraA9Ram6mearaAcbamzNjjjbgKamfgw9RcK6mdcbhYaDcjlfhAinaDcjlfaYfh8AcwhCczhLcehQindndnaQce9hmbcuhoa8ARbbmecbhodninaogecsSmeaecefhoaAaefcefRbbTmbkkcucbaecs6EhoxekaQcetc;:FFFeGhocuaQtcu7cFeGhXcbheinaoaXaAaefRbb9nfhoaecefgecz9hmbkkaoaLaoaL6geEhLaQaCaeEhCaQcetgQcw6mbkdndndndnaCcufPdiebkaKaYco4fgeaeRbbcdciaCclSEaYci4coGtV86bbaCcw9hmeawa8A8Pbb83bbawcwfa8Acwf8Pbb83bbawczfhwxdkaKaYco4fgeaeRbbceaYci4coGtV86bbkdncwaC9TgEmbinawcb86bbawcefhwxbkkcuaCtcu7h8Acbh3aAh5ina5heaEhQcbhoinaeRbbgLa8AcFeGgXaLaX6EaoaCtVhoaecefheaQcufgQmbkawao86bba5aEfh5awcefhwa3aEfg3cz6mbkcbheindnaAaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaYczfgYas9pmbaAczfhAaraw9RcL0mekkaYas6meawTmeaOcefhOazcefgzal6hHawhAazalSmixbkkcbhwaHceGTmexikcbhwaHceGmdkaDaPaxcufal2falz:tjjjb8AaxakfhkawmbkcbhoxokcbhoxvkaiTmekcbhoaraw9Ralcaalca0E6mialc8F9nmexdkcbhoaecufca6mdkawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9Rhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBd:S:kjjbk;rse3u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:C:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgoydbhLaocwfydbhKaoclfydbhYcbh8Adndninalc;abfavcsGcitfgoydlhEdndndnaoydbgoaL9hmbaEaYSmekdnaoaY9hmbaEaK9hmba8Acefh8AxekaoaK9hmeaEaL9hmea8Acdfh8Aka8Ac870mdaXcufhvada8AciGcx2goc:y1jjbfydbaCfcdtfydbhEadaocN1jjbfydbaCfcdtfydbhKadaoc:q1jjbfydbaCfcdtfydbhLcbhodnindnalavcsGcdtfydbaE9hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaEaOSgvaYce9iaYaH9oVgoGh3dndndndndncbcsavEaYaoEgvcs9hmbarce9imbaEaEaAaEcefaASgvEgAcefSmecmcsavEhvkasava8Acdtc;WeGV86bbavcs9hmeaEaA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbkaEhAxdkcPhvasa8AcdtcPV86bbaEhAkavTmbavaH9imekalaXcdtfaEBdbaXcefcsGhXkaOa3fhOalc;abfaQcitfgvaKBdlavaEBdbalc;abfaQcefcsGgvcitfgoaEBdlaoaLBdbavcefhoxikavcufhva8Aclfg8Ac;ab9hmbkkdnadceaKaOScetaYaOSEcx2gvc:q1jjbfydbaCfcdtfydbgLTadavcN1jjbfydbaCfcdtfydbg8AceSGadavc:y1jjbfydbaCfcdtfydbgYcdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhKxdkcuhKaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydbaY9hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaLaOSg8Efh3dndnaKcm0mbaKcefhKxekcbcsa8Aa3SgvEhKa3avfh3kdndnaEcm0mbaEcefhExekcbcsaYa3SgvEhEa3avfh3kc9:cua8EEh8FaEaKcltVhocbhvdndndninavcj1jjbfRbbaocFeGSmeavcefgvcz9hmbxdkka5aLaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeao86bbaecefhekdna8EmbaLaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaLhAkdnaKcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmbaYaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaYhAkalaXcdtfaLBdbaXcefcsGhvdndnaKPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfaYBdbavcefcsGhvkalc;abfaQcitfgoaLBdlaoa8ABdbalc;abfaQcefcsGcitfgoa8ABdlaoaYBdbalc;abfaQcdfcsGcitfgoaYBdlaoaLBdbaQcifhoavhXa3hOkascefhsaocsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:C:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:C:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:dvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhralcxfIdbhqdndnakJbbbb9GTmbaxhkxekJbbjZar:l:tgkak:maxJbbbb9GEhkJbbjZax:l:tgxax:marJbbbb9GEhrkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEavNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohmxekcjjjj94hmkdndnakJbbj:;akJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;akJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;klld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicdfciGcdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:Hvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6mearcearce0EhwaohDinaDc:CuBdbaDclfhDawcufgwmbkaeTmiadcl6mdarcearce0EhqarcdthkalhxcbhminaohDaxhwaqhPinaDaDydbgsawydbgzcL4cFeGc:cufcbazEgzasaz9kEBdbawclfhwaDclfhDaPcufgPmbkaxakfhxamcefgmae9hmbkkaeTmdxekaeTmekavcb9hadcl6gqVhHarcearce0Ehkarcdthrceai9Rhmcbhdindndndnavce9hmbaqmdc:CuhwalhDakhPinawaDydbgscL4cFeGc:cufcbasEgsawas9kEhwaDclfhDaPcufgPmbxdkkc:CuhwaHmbaohDalhPakhsinaDaPydbgzcL4cFeGgxc8Aaxc8A9kEc:cufcbazEBdbaPclfhPaDclfhDascufgsmbkkaqmbcbhDakhsinawhPdnavceSmbaoaDfydbhPkdndnalaDfIdbgOcjjj;8iamaPfgPcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohzxekcjjjj94hzkabaDfazcFFFrGaPcKtVBdbaDclfhDascufgsmbkkabarfhbalarfhladcefgdae9hmbkkaocjdf8KjjjjbkFkdCui998Jjjjjbc:Gd9Rgv8Kjjjjbavc:4efcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgoadcFFFFi0Ecbyd:K:kjjbHjjjjbbgeBd:4eavceBd:ydaeabaoz:tjjjb8Akavc:OefcwfcbBdbav9cb83i:Oeavc:Oefaeadaiavc:4efz:njjjbcuaicdtgraicFFFFi0Egwcbyd:K:kjjbHjjjjbbhoavc:4efavyd:ydgDcdtfaoBdbavaDcefgqBd:ydaoavyd:Oegkarz:tjjjbhxavc:4efaqcdtfadci9Ugmcbyd:K:kjjbHjjjjbbgoBdbavaDcdfgrBd:ydaocbamzNjjjbhPavc:4efarcdtfawcbyd:K:kjjbHjjjjbbgsBdbavaDcifgqBd:ydaxhoashrinaralIdbalaoydbgwcwawcw6Ecdtfc;ebfIdbMUdbaoclfhoarclfhraicufgimbkavc:4efaqcdtfcuamcdtadcFFFF970Ecbyd:K:kjjbHjjjjbbgqBdbavaDclfBd:yddnadci6mbamceamce0EhiaehoaqhrinarasaoydbcdtfIdbasaoclfydbcdtfIdbMasaocwfydbcdtfIdbMUdbaocxfhoarclfhraicufgimbkkavc;qbfhzavhoavyd:SehHavyd:WehOcbhwcbhrcbhAcehCinaohXcihQaearci2gLcdtfgocwfydbhdaoydbhDabaAcx2fgiclfaoclfydbgKBdbaiaDBdbaicwfadBdbaParfce86bbazadBdwazaKBdlazaDBdbaqarcdtfcbBdbdnawTmbcihQaXhiinazaQcdtfaiydbgoBdbaQaoaD9haoaK9hGaoad9hGfhQaiclfhiawcufgwmbkkaAcefhAaxaDcdtfgoaoydbcufBdbaxaKcdtfgoaoydbcufBdbaxadcdtfgoaoydbcufBdbcbhwinaOaHaeawaLfcdtfydbcdtgifydbcdtfgKhoakaifgDydbgdhidnadTmbdninaoydbarSmeaoclfhoaicufgiTmdxbkkaoadcdtaKfc98fydbBdbaDaDydbcufBdbkawcefgwci9hmbkdndndnaQTmbcuhrJbbbbhYcbhDavyd:SehKavyd:WehLindndnakazaDcdtfydbcdtgofydbgimbaDcefhDxekaDcs0hwasaofgdIdbh8AadalcbaDcefgDawEcdtfIdbalaxaofydbgwcwawcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEaicdthiaLaKaofydbcdtfhoinaqaoydbgwcdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYawaradEhraoclfhoaic98fgimbkkaDaQ9hmbkarcu9hmekaCam9pmeindnaPaCfRbbmbaChrxdkamaCcefgC9hmbxdkkaQczaQcz6EhwazhoaXhzarcu9hmekkavyd:ydhokaocdtavc:4effc98fhrdninaoTmearydbcbyd:G:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:Gdf8Kjjjjbk;UlevucuaicdtgvaicFFFFi0Egocbyd:K:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhwdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbawceawce0EhDabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;:kivuo99lu8Jjjjjbcj;Hb9Rgl8Kjjjjbcbhvalc1;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:K:kjjbHjjjjbbgrBd19GalceBd;O9Galcwfcbyd:m:kjjbBdbalcb8Pd:e:kjjb83ibalc;W;Gbfcwfcbyd:y:kjjbBdbalcb8Pd:q:kjjb83i;W9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;W;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;49GhDalIdlhkalId;09GhxalIdbhmalId;W9GhPkdndnadTmbJbbbbJbbjZaPam:tJbbbb:xgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhialaocbyd:K:kjjbHjjjjbbgzBd:m9GdnadTmbabhHinaHaiBdbaHclfhHadaicefgi9hmbkadTmbabhiadhHinalaraiydbgecdtfydbcFrGcx2fgvavydbgvcefBdbazavcdtfaeBdbaiclfhiaHcufgHmbkazhiadhHinalaraiydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaiclfhiaHcufgHmbkabhiadhHinalaraiydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwazavcdtfaeBdbaiclfhiaHcufgHmbkadTmbcbhiinabazydbcdtfaiBdbazclfhzadaicefgi9hmbkkclhidninaic98Smealc1;Gbfaifydbcbyd:G:kjjbH:bjjjbbaic98fhixbkkalcj;Hbf8Kjjjjbk9teiucbcbyd:O:kjjbgeabcifc98GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:O:kjjbgeabcrfc94GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:O:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:O:kjjbfgdBd:O:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:6ddbcjwk:Cdb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:FFuuFFuuFFuuFFuFFFuFFFuFbc:Cqkzebbbebbbdbbb8WWbb"; + var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:W;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXqF9qLdbk;3keYu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRb:S:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9UhodndndndndnalTmbaoc;WFbGgecjdaecjd6Ehqcbhkdninakai9pmiaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndndndnaec9WGgsTmbcbhzcehHaPhOawhAxekdnaxTmbcbhAcehHaPhCinaDaAfRbbhXaDcjlfheaChoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkaraw9Ram6miawcbamzNjjjbgeTmiaCcefhCaeamfhwaAcefgAal6hHaAal9hmbxvkkaraw9Ram6mvawcbamzNjjjb8AceheinawgXamfhwalaegoSmldnaraw9Ram6mbaocefheawcbamzNjjjb8AaXmekkaoal6hHxekindnaxTmbaDazfRbbhXaDcjlfheaOhoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkkaraA9Ram6mearaAcbamzNjjjbgKamfgw9RcK6mdcbhYaDcjlfhAinaDcjlfaYfh8AcwhCczhLcehQindndnaQce9hmbcuhoa8ARbbmecbhodninaogecsSmeaecefhoaAaefcefRbbTmbkkcucbaecs6EhoxekaQcetc;:FFFeGhocuaQtcu7cFeGhXcbheinaoaXaAaefRbb9nfhoaecefgecz9hmbkkaoaLaoaL6geEhLaQaCaeEhCaQcetgQcw6mbkdndndndnaCcufPdiebkaKaYco4fgeaeRbbcdciaCclSEaYci4coGtV86bbaCcw9hmeawa8A8Pbb83bbawcwfa8Acwf8Pbb83bbawczfhwxdkaKaYco4fgeaeRbbceaYci4coGtV86bbkdncwaC9TgEmbinawcb86bbawcefhwxbkkcuaCtcu7h8Acbh3aAh5ina5heaEhQcbhoinaeRbbgLa8AcFeGgXaLaX6EaoaCtVhoaecefheaQcufgQmbkawao86bba5aEfh5awcefhwa3aEfg3cz6mbkcbheindnaAaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaYczfgYas9pmbaAczfhAaraw9RcL0mekkaYas6meawTmeaOcefhOazcefgzal6hHawhAazalSmixbkkcbhwaHceGTmexikcbhwaHceGmdkaDaPaxcufal2falz:tjjjb8AaxakfhkawmbkcbhoxokcbhoxvkaiTmekcbhoaraw9Ralcaalca0E6mialc8F9nmexdkcbhoaecufca6mdkawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9Rhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBd:S:kjjbk;rse3u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:C:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgoydbhLaocwfydbhKaoclfydbhYcbh8Adndninalc;abfavcsGcitfgoydlhEdndndnaoydbgoaL9hmbaEaYSmekdnaoaY9hmbaEaK9hmba8Acefh8AxekaoaK9hmeaEaL9hmea8Acdfh8Aka8Ac870mdaXcufhvada8AciGcx2goc:y1jjbfydbaCfcdtfydbhEadaocN1jjbfydbaCfcdtfydbhKadaoc:q1jjbfydbaCfcdtfydbhLcbhodnindnalavcsGcdtfydbaE9hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaEaOSgvaYce9iaYaH9oVgoGh3dndndndndncbcsavEaYaoEgvcs9hmbarce9imbaEaEaAaEcefaASgvEgAcefSmecmcsavEhvkasava8Acdtc;WeGV86bbavcs9hmeaEaA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbkaEhAxdkcPhvasa8AcdtcPV86bbaEhAkavTmbavaH9imekalaXcdtfaEBdbaXcefcsGhXkaOa3fhOalc;abfaQcitfgvaKBdlavaEBdbalc;abfaQcefcsGgvcitfgoaEBdlaoaLBdbavcefhoxikavcufhva8Aclfg8Ac;ab9hmbkkdnadceaKaOScetaYaOSEcx2gvc:q1jjbfydbaCfcdtfydbgLTadavcN1jjbfydbaCfcdtfydbg8AceSGadavc:y1jjbfydbaCfcdtfydbgYcdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhKxdkcuhKaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydbaY9hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaLaOSg8Efh3dndnaKcm0mbaKcefhKxekcbcsa8Aa3SgvEhKa3avfh3kdndnaEcm0mbaEcefhExekcbcsaYa3SgvEhEa3avfh3kc9:cua8EEh8FaEaKcltVhocbhvdndndninavcj1jjbfRbbaocFeGSmeavcefgvcz9hmbxdkka5aLaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeao86bbaecefhekdna8EmbaLaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaLhAkdnaKcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmbaYaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaYhAkalaXcdtfaLBdbaXcefcsGhvdndnaKPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfaYBdbavcefcsGhvkalc;abfaQcitfgoaLBdlaoa8ABdbalc;abfaQcefcsGcitfgoa8ABdlaoaYBdbalc;abfaQcdfcsGcitfgoaYBdlaoaLBdbaQcifhoavhXa3hOkascefhsaocsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:C:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:C:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:dvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhralcxfIdbhqdndnakJbbbb9GTmbaxhkxekJbbjZar:l:tgkak:maxJbbbb9GEhkJbbjZax:l:tgxax:marJbbbb9GEhrkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEavNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohmxekcjjjj94hmkdndnakJbbj:;akJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;akJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;klld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicdfciGcdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:Hvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6mearcearce0EhwaohDinaDc:CuBdbaDclfhDawcufgwmbkaeTmiadcl6mdarcearce0EhqarcdthkalhxcbhminaohDaxhwaqhPinaDaDydbgsawydbgzcL4cFeGc:cufcbazEgzasaz9kEBdbawclfhwaDclfhDaPcufgPmbkaxakfhxamcefgmae9hmbkkaeTmdxekaeTmekavcb9hadcl6gqVhHarcearce0Ehkarcdthrceai9Rhmcbhdindndndnavce9hmbaqmdc:CuhwalhDakhPinawaDydbgscL4cFeGc:cufcbasEgsawas9kEhwaDclfhDaPcufgPmbxdkkc:CuhwaHmbaohDalhPakhsinaDaPydbgzcL4cFeGgxc8Aaxc8A9kEc:cufcbazEBdbaPclfhPaDclfhDascufgsmbkkaqmbcbhDakhsinawhPdnavceSmbaoaDfydbhPkdndnalaDfIdbgOcjjj;8iamaPfgPcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohzxekcjjjj94hzkabaDfazcFFFrGaPcKtVBdbaDclfhDascufgsmbkkabarfhbalarfhladcefgdae9hmbkkaocjdf8Kjjjjbk;4qdAui998Jjjjjbc:Gd9Rgv8Kjjjjbavc:4efcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgoadcFFFFi0Ecbyd:K:kjjbHjjjjbbgeBd:4eavceBd:ydaeabaoz:tjjjb8Akavc:OefcwfcbBdbav9cb83i:Oeavc:Oefaeadaiavc:4efz:njjjbavyd:Oehradci9Ugwcbyd:K:kjjbHjjjjbbhoavc:4efavyd:ydgDcdtfaoBdbavaDcefgqBd:ydaocbawzNjjjbhkavc:4efaqcdtfcuaicdtaicFFFFi0Ecbyd:K:kjjbHjjjjbbgxBdbavaDcdfgmBd:ydarhoaxhqinaqalIdbalaoydbgPcwaPcw6Ecdtfc;ebfIdbMUdbaoclfhoaqclfhqaicufgimbkavc:4efamcdtfcuawcdtadcFFFF970Ecbyd:K:kjjbHjjjjbbgmBdbavaDcifBd:yddnadci6mbawceawce0EhiaehoamhqinaqaxaoydbcdtfIdbaxaoclfydbcdtfIdbMaxaocwfydbcdtfIdbMUdbaocxfhoaqclfhqaicufgimbkkavc;qbfhsavhoavyd:Sehzavyd:WehHcbhPcbhqcbhOcehAinaohCcihXaeaqci2gQcdtfgocwfydbhdaoydbhDabaOcx2fgiclfaoclfydbgLBdbaiaDBdbaicwfadBdbakaqfce86bbasadBdwasaLBdlasaDBdbamaqcdtfcbBdbdnaPTmbcihXaChiinasaXcdtfaiydbgoBdbaXaoad9haoaD9haoaL9hGGfhXaiclfhiaPcufgPmbkkaOcefhOcbhPinaHazaeaPaQfcdtfydbcdtgifydbcdtfgLhoaraifgDydbgdhidnadTmbdninaoydbaqSmeaoclfhoaicufgiTmdxbkkaoadcdtaLfc98fydbBdbaDaDydbcufBdbkaPcefgPci9hmbkdndndnaXTmbcuhqJbbbbhKcbhDavyd:SehLavyd:WehQindndnarasaDcdtfydbcdtgPfydbgombaDcefhDxekaDcs0hiaxaPfgdIdbhYadalcbaDcefgDaiEcdtfIdbalaocwaocw6Ecdtfc;ebfIdbMg8AUdba8AaY:th8AaocdthiaQaLaPfydbcdtfhoinamaoydbgPcdtfgda8AadIdbMgYUdbaYaKaKaY9DgdEhKaPaqadEhqaoclfhoaic98fgimbkkaDaX9hmbkaqcu9hmekaAaw9pmeindnakaAfRbbmbaAhqxdkawaAcefgA9hmbxdkkaXczaXcz6EhPashoaChsaqcu9hmekkavyd:ydhokaocdtavc:4effc98fhqdninaoTmeaqydbcbyd:G:kjjbH:bjjjbbaqc98fhqaocufhoxbkkavc:Gdf8Kjjjjbk;UlevucuaicdtgvaicFFFFi0Egocbyd:K:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhwdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbawceawce0EhDabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;:kivuo99lu8Jjjjjbcj;Hb9Rgl8Kjjjjbcbhvalc1;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:K:kjjbHjjjjbbgrBd19GalceBd;O9Galcwfcbyd:m:kjjbBdbalcb8Pd:e:kjjb83ibalc;W;Gbfcwfcbyd:y:kjjbBdbalcb8Pd:q:kjjb83i;W9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;W;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;49GhDalIdlhkalId;09GhxalIdbhmalId;W9GhPkdndnadTmbJbbbbJbbjZaPam:tJbbbb:xgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhialaocbyd:K:kjjbHjjjjbbgzBd:m9GdnadTmbabhHinaHaiBdbaHclfhHadaicefgi9hmbkadTmbabhiadhHinalaraiydbgecdtfydbcFrGcx2fgvavydbgvcefBdbazavcdtfaeBdbaiclfhiaHcufgHmbkazhiadhHinalaraiydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaiclfhiaHcufgHmbkabhiadhHinalaraiydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwazavcdtfaeBdbaiclfhiaHcufgHmbkadTmbcbhiinabazydbcdtfaiBdbazclfhzadaicefgi9hmbkkclhidninaic98Smealc1;Gbfaifydbcbyd:G:kjjbH:bjjjbbaic98fhixbkkalcj;Hbf8Kjjjjbk9teiucbcbyd:O:kjjbgeabcifc98GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:O:kjjbgeabcrfc94GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:O:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:O:kjjbfgdBd:O:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:6ddbcjwk:Cdb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:FFuuFFuuFFuuFFuFFFuFFFuFbc:Cqkzebbbebbbdbbb8WWbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); From d03d753d11cc223b99349242502a806077e23de4 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Apr 2024 16:35:05 -0700 Subject: [PATCH 044/581] js: Update meshopt_simplifier after vertex_lock changes This change reverts the code style changes to keep code consistent and avoids overriding vertex_lock with the value of a different type. --- js/meshopt_simplifier.js | 34 ++++++++++++++++----------------- js/meshopt_simplifier.module.js | 32 +++++++++++++++---------------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 123fcf4bdb..9c9a12fc09 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -1,12 +1,12 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -var MeshoptSimplifier = (function () { +var MeshoptSimplifier = (function() { "use strict"; // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;H9Usdbk;N6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascwfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd1:jjjbHjjjjbbgHBdwasceBd9OasaHBdbascuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgOBdxascdBd9OasaOBdlasaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd1:jjjbHjjjjbbgXBdzasciBd9OasaCcbyd1:jjjbHjjjjbbgQBdCasclBd9Oalcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd1:jjjbHjjjjbbgLBdKascvBd9OaLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd:m:jjjbH:bjjjbbasclBd9Oasalcbyd1:jjjbHjjjjbbg3BdKascvBd9OasaCcbyd1:jjjbHjjjjbbgzBd3ascoBd9OasaCcbyd1:jjjbHjjjjbbgKBdaascrBd9OazcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Kascwfasyd9Ogzcdtfa8KBdbasazcefgABd9Oa8Kaialavz:djjjbdndnaDmbcbhvxekcbh8EascwfaAcdtfcuaDal2gKcdtaKcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbasazcdfgABd9OalTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascwfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd1:jjjbHjjjjbbgKBdbasaAcefg5Bd9OaKcbazz:ljjjbh8FdndndnaDTmbascwfa5cdtfaLcbyd1:jjjbHjjjjbbgoBdbasaAcdfgKBd9Oaocbazz:ljjjb8AascwfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd1:jjjbHjjjjbbgqBdbasaAcifBd9OaqcbaKz:ljjjb8AadmexdkcbhocbhqadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Eaeh8AincbhKina3aeaKc:G1jjbfydba8EfcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:W1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekJbbacJbbjZazceSEh8RaEceShAa8KaeaKc:K1jjbfydba8Efcdtfydbcx2fhzdna8KaLcx2fgEIdwa8Ka5cx2fgYIdwg8P:tgIaINaEIdbaYIdbg8U:tgyayNaEIdlaYIdlg8S:tgRaRNMM:rg8NJbbbb9ETmbaIa8N:vhIaRa8N:vhRaya8N:vhykJbbaca8RaAEh8XdnazIdwa8P:tg8RaIa8RaINazIdba8U:tg8YayNaRazIdla8S:tg8WNMMg8VN:tg8Ra8RNa8Yaya8VN:tgIaINa8WaRa8VN:tgyayNMM:rgRJbbbb9ETmba8RaR:vh8RayaR:vhyaIaR:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNgRaINNg8VazIdbMUdbazayaRayNg8XNg8YazIdlMUdlaza8RaRa8RNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIaRa8Ra8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3aza8Ra8NNg8RazIdaMUdaaza8Na8PNg8NazId8KMUd8KazaRazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3aza8RazIdaMUdaaza8NazId8KMUd8KazaRazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Ecifg8Ead6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tg8Ra8RNaKIdlaLIdlg80:tgRaRNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNa8RazIdba8Z:tg8PNaRazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNaRaIN:ta8VNh83a8YaRNa8SaIN:ta8VNhUa8Xa8PNa8RaIN:ta8VNh85a8Ya8RNa8PaIN:ta8VNh86a8Ra8SNa8PaRN:tgIaINaRa8NNa8SayN:tgIaINaya8PNa8Na8RN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tgRNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUaRNa83a8PNMg8RNUdbazaIa86aRNa85a8PNMgRNUdbazcxfaIa87ayNa88a8RNa8Na89aRNMMMg8NNUdbaIaya8RNNa8YMh8YaIayaRNNa8WMh8WaIa8RaRNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIa8Ra8NNNa8VMh8VaIaRa8NNNa8XMh8XaIayayNNa80Mh80aIa8Ra8RNNa8:Mh8:aIaRaRNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaoaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydbhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Mascwfasyd9Ogzcdtfa8MBdbasazcefgKBd9OascwfaKcdtfcuamcdtamcFFFFi0Ecbyd1:jjjbHjjjjbbgwBdbasazcdfgKBd9OascwfaKcdtfaCcbyd1:jjjbHjjjjbbgOBdbasazcifgKBd9OascwfaKcdtfalcbyd1:jjjbHjjjjbbgcBdbasazclfBd9OJbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasabadggalaXz:cjjjbabhAcbhHcbhYincbhzindnaXaAazfydbgLcdtg8AfydbgEaXabazc;m1jjbfydbaYfcdtfydbgKcdtfydbg8ESmba3aKfRbbgecv2a3aLfRbbg5fc;G1jjbfRbbg8La5cv2aefg8Jc;G1jjbfRbbgiVcFeGTmbdna8Jc:W1jjbfRbbTmba8EaE0mekdna5ae9hmba5cufcFeGce0mbaaa8AfydbaK9hmeka8MaHcx2fg5aKaLaicFeGgEEBdla5aLaKaEEBdba5aEa8LGcb9hBdwaHcefhHkazclfgzcx9hmbkdnaYcifgYag9pmbaAcxfhAaHcifam9nmekkdnaHmbaghdxikcbheinJbbbbJbbjZa8FaXa8Maecx2fg5ydlgEa5ydbg8Ea5ydwgKEgYcdtfydbg8Lc8S2gifgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEg8Acx2fgKIdwgRNazIdzaKIdbg8NNazIdaMgIaIMMaRNazIdlaKIdlg8PNazIdCaRNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbgdc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwg8RNazIdzaKIdbg8UNazIdaMgIaIMMa8RNazIdlaKIdlg8SNazIdCa8RNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfhAa5clfh8JdnaDTmbaoaLfgLIdwa8RNaLIdza8UNaLIdaMgIaIMMa8RNaLIdla8SNaLIdCa8RNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKaqadaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaoaifgLIdwaRNaLIdza8NNaLIdaMgIaIMMaRNaLIdla8PNaLIdCaRNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMh8Rava8AaD2cdtfhKaqa8LaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNa8RMMh8RaKclfhKazczfhzaLcufgLmbka8Xa8R:lMh8Xa8Yay:lMh8Yka8JaEa8Aa8Ya8X9FgzEBdba5a8EaYazEBdbaAa8Ya8XazEUdbaecefgeaH9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzaHhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbawaLcdtfazBdbaKcxfhKaHazcefgz9hmbkagak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydlh6cbhicbh8Jdnina8Mawa8Jcdtfydbcx2fgAIdwgya8W9Emeaia9e9pmeJFFuuhIdna9iaH9pmba8Mawa9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaia9h0mdkdnaSaXaAydlg9kcdtg0fydbg5fg9mRbbaSaXaAydbgYcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fg8Acwfhda8AclfhCa8Ka9ocx2fg8Lcwfhra8Lclfh9qcbhKcehednindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbg8R:tgIa9qIdbaLIdlgR:tg8NNa8LIdba8R:tg8PaEIdlaR:tgyN:taIaCIdbaR:tg8UNa8AIdba8R:tg8SayN:tNayarIdbaLIdwgR:tg8VNa8NaEIdwaR:tg8RN:tayadIdbaR:tgRNa8Ua8RN:tNa8Ra8PNa8VaIN:ta8Ra8SNaRaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6hea8EaK9hmbkkaeceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaoaLfgzaoaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2hea9ca52h8AaqhKaDhEinaKa8AfgzaKaefgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkkaAcwfhKdndndndna3aYfgLRbbc9:fPdebdkaYhzinaOazcdtgzfa5BdbaQazfydbgzaY9hmbxikkaQa0fydbhzaQa9nfydbhYaOa9nfa9kBdbazh9kkaOaYcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaifhika8Jcefg8JaH9hmbkkdnaTmbaghdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8EclfaLBdba8Ecwfa5BdbadcifhdkazcxfhzaEcifgEag6mbkadak9nmdxbkkasabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd9Ogzcdtascwffc98fhXdninazTmeaXydbcbyd:m:jjjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; - var wasmpack = new Uint8Array([32, 0, 65, 2, 1, 106, 34, 33, 3, 128, 11, 4, 13, 64, 6, 253, 10, 7, 15, 116, 127, 5, 8, 12, 40, 16, 19, 54, 20, 9, 27, 255, 113, 17, 42, 67, 24, 23, 146, 148, 18, 14, 22, 45, 70, 69, 56, 114, 101, 21, 25, 63, 75, 136, 108, 28, 118, 29, 73, 115]); + var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); if (typeof WebAssembly !== 'object') { return { @@ -18,10 +18,10 @@ var MeshoptSimplifier = (function () { var ready = WebAssembly.instantiate(unpack(wasm), {}) - .then(function (result) { - instance = result.instance; - instance.exports.__wasm_call_ctors(); - }); + .then(function(result) { + instance = result.instance; + instance.exports.__wasm_call_ctors(); + }); function unpack(data) { var result = new Uint8Array(data.length); @@ -104,14 +104,15 @@ var MeshoptSimplifier = (function () { var sa = sbrk(vertex_count * vertex_attributes_stride); var sw = sbrk(attribute_weights.length * 4); var si = sbrk(index_count * 4); - var vl = vertex_lock && sbrk(vertex_count); + var vl = vertex_lock ? sbrk(vertex_count) : 0; var heap = new Uint8Array(instance.exports.memory.buffer); heap.set(bytes(vertex_positions), sp); heap.set(bytes(vertex_attributes), sa); heap.set(bytes(attribute_weights), sw); heap.set(bytes(indices), si); - if (vertex_lock) + if (vertex_lock) { heap.set(bytes(vertex_lock), vl); + } var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, sa, vertex_attributes_stride, sw, attribute_weights.length, vl, target_index_count, target_error, options, te); // heap may have grown heap = new Uint8Array(instance.exports.memory.buffer); @@ -164,7 +165,7 @@ var MeshoptSimplifier = (function () { // note that these functions are experimental and may change interface/behavior in a way that will require revising calling code useExperimentalFeatures: false, - compactMesh: function (indices) { + compactMesh: function(indices) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -172,7 +173,7 @@ var MeshoptSimplifier = (function () { return reorder(instance.exports.meshopt_optimizeVertexFetchRemap, indices32, maxindex(indices) + 1); }, - simplify: function (indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { + simplify: function(indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); assert(vertex_positions instanceof Float32Array); @@ -194,7 +195,7 @@ var MeshoptSimplifier = (function () { return result; }, - simplifyWithAttributes: function (indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, flags) { + simplifyWithAttributes: function(indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, flags) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -217,24 +218,21 @@ var MeshoptSimplifier = (function () { options |= simplifyOptions[flags[i]]; } - if (vertex_lock) - vertex_lock = new Uint8Array(vertex_lock); - var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices); - var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), vertex_lock, target_index_count, target_error, options); + var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), vertex_lock ? new Uint8Array(vertex_lock) : null, target_index_count, target_error, options); result[0] = (indices instanceof Uint32Array) ? result[0] : new indices.constructor(result[0]); return result; }, - getScale: function (vertex_positions, vertex_positions_stride) { + getScale: function(vertex_positions, vertex_positions_stride) { assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); assert(vertex_positions_stride >= 3); return simplifyScale(instance.exports.meshopt_simplifyScale, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4); }, - simplifyPoints: function (vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { + simplifyPoints: function(vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); @@ -257,7 +255,7 @@ var MeshoptSimplifier = (function () { if (typeof exports === 'object' && typeof module === 'object') module.exports = MeshoptSimplifier; else if (typeof define === 'function' && define['amd']) - define([], function () { + define([], function() { return MeshoptSimplifier; }); else if (typeof exports === 'object') diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index 6232b2e50a..645878f925 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -1,11 +1,11 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -var MeshoptSimplifier = (function () { +var MeshoptSimplifier = (function() { // Built with clang version 16.0.0 // Built from meshoptimizer 0.20 var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;H9Usdbk;N6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascwfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd1:jjjbHjjjjbbgHBdwasceBd9OasaHBdbascuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgOBdxascdBd9OasaOBdlasaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd1:jjjbHjjjjbbgXBdzasciBd9OasaCcbyd1:jjjbHjjjjbbgQBdCasclBd9Oalcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd1:jjjbHjjjjbbgLBdKascvBd9OaLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd:m:jjjbH:bjjjbbasclBd9Oasalcbyd1:jjjbHjjjjbbg3BdKascvBd9OasaCcbyd1:jjjbHjjjjbbgzBd3ascoBd9OasaCcbyd1:jjjbHjjjjbbgKBdaascrBd9OazcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Kascwfasyd9Ogzcdtfa8KBdbasazcefgABd9Oa8Kaialavz:djjjbdndnaDmbcbhvxekcbh8EascwfaAcdtfcuaDal2gKcdtaKcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbasazcdfgABd9OalTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascwfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd1:jjjbHjjjjbbgKBdbasaAcefg5Bd9OaKcbazz:ljjjbh8FdndndnaDTmbascwfa5cdtfaLcbyd1:jjjbHjjjjbbgoBdbasaAcdfgKBd9Oaocbazz:ljjjb8AascwfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd1:jjjbHjjjjbbgqBdbasaAcifBd9OaqcbaKz:ljjjb8AadmexdkcbhocbhqadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Eaeh8AincbhKina3aeaKc:G1jjbfydba8EfcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:W1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekJbbacJbbjZazceSEh8RaEceShAa8KaeaKc:K1jjbfydba8Efcdtfydbcx2fhzdna8KaLcx2fgEIdwa8Ka5cx2fgYIdwg8P:tgIaINaEIdbaYIdbg8U:tgyayNaEIdlaYIdlg8S:tgRaRNMM:rg8NJbbbb9ETmbaIa8N:vhIaRa8N:vhRaya8N:vhykJbbaca8RaAEh8XdnazIdwa8P:tg8RaIa8RaINazIdba8U:tg8YayNaRazIdla8S:tg8WNMMg8VN:tg8Ra8RNa8Yaya8VN:tgIaINa8WaRa8VN:tgyayNMM:rgRJbbbb9ETmba8RaR:vh8RayaR:vhyaIaR:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNgRaINNg8VazIdbMUdbazayaRayNg8XNg8YazIdlMUdlaza8RaRa8RNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIaRa8Ra8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3aza8Ra8NNg8RazIdaMUdaaza8Na8PNg8NazId8KMUd8KazaRazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3aza8RazIdaMUdaaza8NazId8KMUd8KazaRazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Ecifg8Ead6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tg8Ra8RNaKIdlaLIdlg80:tgRaRNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNa8RazIdba8Z:tg8PNaRazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNaRaIN:ta8VNh83a8YaRNa8SaIN:ta8VNhUa8Xa8PNa8RaIN:ta8VNh85a8Ya8RNa8PaIN:ta8VNh86a8Ra8SNa8PaRN:tgIaINaRa8NNa8SayN:tgIaINaya8PNa8Na8RN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tgRNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUaRNa83a8PNMg8RNUdbazaIa86aRNa85a8PNMgRNUdbazcxfaIa87ayNa88a8RNa8Na89aRNMMMg8NNUdbaIaya8RNNa8YMh8YaIayaRNNa8WMh8WaIa8RaRNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIa8Ra8NNNa8VMh8VaIaRa8NNNa8XMh8XaIayayNNa80Mh80aIa8Ra8RNNa8:Mh8:aIaRaRNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaoaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydbhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Mascwfasyd9Ogzcdtfa8MBdbasazcefgKBd9OascwfaKcdtfcuamcdtamcFFFFi0Ecbyd1:jjjbHjjjjbbgwBdbasazcdfgKBd9OascwfaKcdtfaCcbyd1:jjjbHjjjjbbgOBdbasazcifgKBd9OascwfaKcdtfalcbyd1:jjjbHjjjjbbgcBdbasazclfBd9OJbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasabadggalaXz:cjjjbabhAcbhHcbhYincbhzindnaXaAazfydbgLcdtg8AfydbgEaXabazc;m1jjbfydbaYfcdtfydbgKcdtfydbg8ESmba3aKfRbbgecv2a3aLfRbbg5fc;G1jjbfRbbg8La5cv2aefg8Jc;G1jjbfRbbgiVcFeGTmbdna8Jc:W1jjbfRbbTmba8EaE0mekdna5ae9hmba5cufcFeGce0mbaaa8AfydbaK9hmeka8MaHcx2fg5aKaLaicFeGgEEBdla5aLaKaEEBdba5aEa8LGcb9hBdwaHcefhHkazclfgzcx9hmbkdnaYcifgYag9pmbaAcxfhAaHcifam9nmekkdnaHmbaghdxikcbheinJbbbbJbbjZa8FaXa8Maecx2fg5ydlgEa5ydbg8Ea5ydwgKEgYcdtfydbg8Lc8S2gifgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEg8Acx2fgKIdwgRNazIdzaKIdbg8NNazIdaMgIaIMMaRNazIdlaKIdlg8PNazIdCaRNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbgdc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwg8RNazIdzaKIdbg8UNazIdaMgIaIMMa8RNazIdlaKIdlg8SNazIdCa8RNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfhAa5clfh8JdnaDTmbaoaLfgLIdwa8RNaLIdza8UNaLIdaMgIaIMMa8RNaLIdla8SNaLIdCa8RNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKaqadaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaoaifgLIdwaRNaLIdza8NNaLIdaMgIaIMMaRNaLIdla8PNaLIdCaRNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMh8Rava8AaD2cdtfhKaqa8LaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNa8RMMh8RaKclfhKazczfhzaLcufgLmbka8Xa8R:lMh8Xa8Yay:lMh8Yka8JaEa8Aa8Ya8X9FgzEBdba5a8EaYazEBdbaAa8Ya8XazEUdbaecefgeaH9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzaHhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbawaLcdtfazBdbaKcxfhKaHazcefgz9hmbkagak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydlh6cbhicbh8Jdnina8Mawa8Jcdtfydbcx2fgAIdwgya8W9Emeaia9e9pmeJFFuuhIdna9iaH9pmba8Mawa9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaia9h0mdkdnaSaXaAydlg9kcdtg0fydbg5fg9mRbbaSaXaAydbgYcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fg8Acwfhda8AclfhCa8Ka9ocx2fg8Lcwfhra8Lclfh9qcbhKcehednindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbg8R:tgIa9qIdbaLIdlgR:tg8NNa8LIdba8R:tg8PaEIdlaR:tgyN:taIaCIdbaR:tg8UNa8AIdba8R:tg8SayN:tNayarIdbaLIdwgR:tg8VNa8NaEIdwaR:tg8RN:tayadIdbaR:tgRNa8Ua8RN:tNa8Ra8PNa8VaIN:ta8Ra8SNaRaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6hea8EaK9hmbkkaeceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaoaLfgzaoaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2hea9ca52h8AaqhKaDhEinaKa8AfgzaKaefgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkkaAcwfhKdndndndna3aYfgLRbbc9:fPdebdkaYhzinaOazcdtgzfa5BdbaQazfydbgzaY9hmbxikkaQa0fydbhzaQa9nfydbhYaOa9nfa9kBdbazh9kkaOaYcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaifhika8Jcefg8JaH9hmbkkdnaTmbaghdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8EclfaLBdba8Ecwfa5BdbadcifhdkazcxfhzaEcifgEag6mbkadak9nmdxbkkasabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd9Ogzcdtascwffc98fhXdninazTmeaXydbcbyd:m:jjjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; - var wasmpack = new Uint8Array([32, 0, 65, 2, 1, 106, 34, 33, 3, 128, 11, 4, 13, 64, 6, 253, 10, 7, 15, 116, 127, 5, 8, 12, 40, 16, 19, 54, 20, 9, 27, 255, 113, 17, 42, 67, 24, 23, 146, 148, 18, 14, 22, 45, 70, 69, 56, 114, 101, 21, 25, 63, 75, 136, 108, 28, 118, 29, 73, 115]); + var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); if (typeof WebAssembly !== 'object') { return { @@ -17,10 +17,10 @@ var MeshoptSimplifier = (function () { var ready = WebAssembly.instantiate(unpack(wasm), {}) - .then(function (result) { - instance = result.instance; - instance.exports.__wasm_call_ctors(); - }); + .then(function(result) { + instance = result.instance; + instance.exports.__wasm_call_ctors(); + }); function unpack(data) { var result = new Uint8Array(data.length); @@ -103,14 +103,15 @@ var MeshoptSimplifier = (function () { var sa = sbrk(vertex_count * vertex_attributes_stride); var sw = sbrk(attribute_weights.length * 4); var si = sbrk(index_count * 4); - var vl = vertex_lock && sbrk(vertex_count); + var vl = vertex_lock ? sbrk(vertex_count) : 0; var heap = new Uint8Array(instance.exports.memory.buffer); heap.set(bytes(vertex_positions), sp); heap.set(bytes(vertex_attributes), sa); heap.set(bytes(attribute_weights), sw); heap.set(bytes(indices), si); - if (vertex_lock) + if (vertex_lock) { heap.set(bytes(vertex_lock), vl); + } var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, sa, vertex_attributes_stride, sw, attribute_weights.length, vl, target_index_count, target_error, options, te); // heap may have grown heap = new Uint8Array(instance.exports.memory.buffer); @@ -163,7 +164,7 @@ var MeshoptSimplifier = (function () { // note that these functions are experimental and may change interface/behavior in a way that will require revising calling code useExperimentalFeatures: false, - compactMesh: function (indices) { + compactMesh: function(indices) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -171,7 +172,7 @@ var MeshoptSimplifier = (function () { return reorder(instance.exports.meshopt_optimizeVertexFetchRemap, indices32, maxindex(indices) + 1); }, - simplify: function (indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { + simplify: function(indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) { assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); assert(vertex_positions instanceof Float32Array); @@ -193,7 +194,7 @@ var MeshoptSimplifier = (function () { return result; }, - simplifyWithAttributes: function (indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, flags) { + simplifyWithAttributes: function(indices, vertex_positions, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, vertex_lock, target_index_count, target_error, flags) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array); assert(indices.length % 3 == 0); @@ -216,24 +217,21 @@ var MeshoptSimplifier = (function () { options |= simplifyOptions[flags[i]]; } - if (vertex_lock) - vertex_lock = new Uint8Array(vertex_lock); - var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices); - var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), vertex_lock, target_index_count, target_error, options); + var result = simplifyAttr(instance.exports.meshopt_simplifyWithAttributes, indices32, indices.length, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4, vertex_attributes, vertex_attributes_stride * 4, new Float32Array(attribute_weights), vertex_lock ? new Uint8Array(vertex_lock) : null, target_index_count, target_error, options); result[0] = (indices instanceof Uint32Array) ? result[0] : new indices.constructor(result[0]); return result; }, - getScale: function (vertex_positions, vertex_positions_stride) { + getScale: function(vertex_positions, vertex_positions_stride) { assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); assert(vertex_positions_stride >= 3); return simplifyScale(instance.exports.meshopt_simplifyScale, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4); }, - simplifyPoints: function (vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { + simplifyPoints: function(vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) { assert(this.useExperimentalFeatures); // set useExperimentalFeatures to use this; note that this function is experimental and may change interface in a way that will require revising calling code assert(vertex_positions instanceof Float32Array); assert(vertex_positions.length % vertex_positions_stride == 0); From 3c3e56d312cbe7d5929c78401de2124c7be3bc07 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Apr 2024 16:40:15 -0700 Subject: [PATCH 045/581] Update vertex_lock documentation for clarity --- src/meshoptimizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index 722ecb0c36..c377eebbc3 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -357,7 +357,7 @@ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsig * vertex_attributes should have attribute_count floats for each vertex * attribute_weights should have attribute_count floats in total; the weights determine relative priority of attributes between each other and wrt position. The recommended weight range is [1e-3..1e-1], assuming attribute data is in [0..1] range. * attribute_count must be <= 16 - * vertex_lock can be NULL; when not NULL, it should have vertex_count chars, 1 for each vertex; they determine which vertices are locked (1) or free to be simplified (0). + * vertex_lock can be NULL; when it's not NULL, it should have a value for each vertex; 1 denotes vertices that can't be moved * TODO target_error/result_error currently use combined distance+attribute error; this may change in the future */ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error); From 9591117afa90d826116d8564dc96d15eabf25869 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Apr 2024 16:45:39 -0700 Subject: [PATCH 046/581] demo: Add tests for simplification with locked vertices The test data is identical to simplifyLockBorder but allows to specify the border explicitly instead of inferring it. --- demo/tests.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/demo/tests.cpp b/demo/tests.cpp index 5eb3d6f2b5..58ec3de18c 100644 --- a/demo/tests.cpp +++ b/demo/tests.cpp @@ -1185,6 +1185,55 @@ static void simplifyAttr() assert(memcmp(ib, expected, sizeof(expected)) == 0); } +static void simplifyLockFlags() +{ + float vb[] = { + 0.000000f, 0.000000f, 0.000000f, + 0.000000f, 1.000000f, 0.000000f, + 0.000000f, 2.000000f, 0.000000f, + 1.000000f, 0.000000f, 0.000000f, + 1.000000f, 1.000000f, 0.000000f, + 1.000000f, 2.000000f, 0.000000f, + 2.000000f, 0.000000f, 0.000000f, + 2.000000f, 1.000000f, 0.000000f, + 2.000000f, 2.000000f, 0.000000f, // clang-format :-/ + }; + + unsigned char lock[9] = { + 1, 1, 1, + 1, 0, 1, + 1, 1, 1, // clang-format :-/ + }; + + // 0 1 2 + // 3 4 5 + // 6 7 8 + + unsigned int ib[] = { + 0, 1, 3, + 3, 1, 4, + 1, 2, 4, + 4, 2, 5, + 3, 4, 6, + 6, 4, 7, + 4, 5, 7, + 7, 5, 8, // clang-format :-/ + }; + + unsigned int expected[] = { + 0, 1, 3, + 1, 2, 3, + 3, 2, 5, + 6, 3, 7, + 3, 5, 7, + 7, 5, 8, // clang-format :-/ + }; + + assert(meshopt_simplifyWithAttributes(ib, ib, 24, vb, 9, 12, NULL, 0, NULL, 0, lock, 3, 1e-3f, 0) == 18); + assert(memcmp(ib, expected, sizeof(expected)) == 0); +} + + static void adjacency() { // 0 1/4 @@ -1399,6 +1448,7 @@ void runTests() simplifyDegenerate(); simplifyLockBorder(); simplifyAttr(); + simplifyLockFlags(); adjacency(); tessellation(); From b936f0ad7e01d2469fe381c2052f4159b17cdd0e Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Apr 2024 16:53:16 -0700 Subject: [PATCH 047/581] js: Fix simplifyWithAttributes type annotation vertex_lock may be null. For now let's keep it as boolean[] although Uint8Array might be more appropriate in the future. --- js/meshopt_simplifier.module.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/meshopt_simplifier.module.d.ts b/js/meshopt_simplifier.module.d.ts index 6c2bdf8374..7e95ad83d8 100644 --- a/js/meshopt_simplifier.module.d.ts +++ b/js/meshopt_simplifier.module.d.ts @@ -13,7 +13,7 @@ export const MeshoptSimplifier: { simplify: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; // Experimental; requires useExperimentalFeatures to be set to true - simplifyWithAttributes: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, vertex_attributes: Float32Array, vertex_attributes_stride: number, attribute_weights: number[], vertex_lock: boolean[], target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; + simplifyWithAttributes: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, vertex_attributes: Float32Array, vertex_attributes_stride: number, attribute_weights: number[], vertex_lock: boolean[] | null, target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; getScale: (vertex_positions: Float32Array, vertex_positions_stride: number) => number; From dba0bee76cd48d8f99dced07e4b76c9c88e7e0e8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 7 Apr 2024 16:34:49 -0400 Subject: [PATCH 048/581] gltfpack: Consolidate image error reporting Instead of printing to stderr manually whenever we have a case when an image can't be saved, call writeImageError; this unifies the error reporting and allows us to produce JSON content that indicates an error. --- gltf/gltfpack.cpp | 4 ++-- gltf/gltfpack.h | 3 ++- gltf/write.cpp | 19 +++++++++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index b20103d3ba..48a0734570 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -480,9 +480,9 @@ static void process(cgltf_data* data, const char* input_path, const char* output if (encoded_images.size() && !encoded_images[i].empty()) { if (encoded_images[i].compare(0, 5, "error") == 0) - fprintf(stderr, "Warning: unable to encode image %d (%s), skipping (%s)\n", int(i), image.uri ? image.uri : "?", encoded_images[i].c_str()); + writeImageError(json_images, "encode", int(i), image.uri, encoded_images[i].c_str()); else - writeEncodedImage(json_images, views, image, encoded_images[i], images[i], output_path, settings); + writeEncodedImage(json_images, views, image, encoded_images[i], images[i], i, output_path, settings); encoded_images[i] = std::string(); // reclaim memory early } diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index 0a2bdf84ea..e22608466e 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -369,7 +369,8 @@ void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_materi void writeBufferView(std::string& json, BufferView::Kind kind, StreamFormat::Filter filter, size_t count, size_t stride, size_t bin_offset, size_t bin_size, BufferView::Compression compression, size_t compressed_offset, size_t compressed_size); void writeSampler(std::string& json, const cgltf_sampler& sampler); void writeImage(std::string& json, std::vector& views, const cgltf_image& image, const ImageInfo& info, size_t index, const char* input_path, const char* output_path, const Settings& settings); -void writeEncodedImage(std::string& json, std::vector& views, const cgltf_image& image, const std::string& encoded, const ImageInfo& info, const char* output_path, const Settings& settings); +void writeImageError(std::string& json, const char* action, size_t index, const char* uri, const char* reason = NULL); +void writeEncodedImage(std::string& json, std::vector& views, const cgltf_image& image, const std::string& encoded, const ImageInfo& info, size_t index, const char* output_path, const Settings& settings); void writeTexture(std::string& json, const cgltf_texture& texture, const ImageInfo* info, cgltf_data* data, const Settings& settings); void writeMeshAttributes(std::string& json, std::vector& views, std::string& json_accessors, size_t& accr_offset, const Mesh& mesh, int target, const QuantizationPosition& qp, const QuantizationTexture& qt, const Settings& settings); size_t writeMeshIndices(std::vector& views, std::string& json_accessors, size_t& accr_offset, const Mesh& mesh, const Settings& settings); diff --git a/gltf/write.cpp b/gltf/write.cpp index 413c96eced..7eae0d6c8e 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -896,7 +896,7 @@ void writeSampler(std::string& json, const cgltf_sampler& sampler) } } -static void writeImageData(std::string& json, std::vector& views, const char* uri, const char* mime_type, const std::string& contents, const char* output_path, TextureKind kind, bool embed) +static void writeImageData(std::string& json, std::vector& views, size_t index, const char* uri, const char* mime_type, const std::string& contents, const char* output_path, TextureKind kind, bool embed) { bool dataUri = uri && strncmp(uri, "data:", 5) == 0; @@ -913,7 +913,7 @@ static void writeImageData(std::string& json, std::vector& views, co } else { - fprintf(stderr, "Warning: unable to save image %s to %s, skipping\n", uri, file_path.c_str()); + writeImageError(json, "save", int(index), uri, file_path.c_str()); } } else @@ -939,16 +939,23 @@ void writeImage(std::string& json, std::vector& views, const cgltf_i std::string mime_type; if (!readImage(image, input_path, img_data, mime_type)) { - fprintf(stderr, "Warning: unable to read image %d (%s), skipping\n", int(index), image.uri ? image.uri : "?"); + writeImageError(json, "read", index, image.uri); return; } - writeImageData(json, views, image.uri, mime_type.c_str(), img_data, output_path, info.kind, settings.texture_embed); + writeImageData(json, views, index, image.uri, mime_type.c_str(), img_data, output_path, info.kind, settings.texture_embed); } -void writeEncodedImage(std::string& json, std::vector& views, const cgltf_image& image, const std::string& encoded, const ImageInfo& info, const char* output_path, const Settings& settings) +void writeImageError(std::string& json, const char* action, size_t index, const char* uri, const char* reason) { - writeImageData(json, views, image.uri, "image/ktx2", encoded, output_path, info.kind, settings.texture_embed); + (void)json; + + fprintf(stderr, "Warning: unable to %s image %d (%s), skipping%s%s%s\n", action, int(index), uri ? uri : "embedded", reason ? " (" : "", reason ? reason : "", reason ? ")" : ""); +} + +void writeEncodedImage(std::string& json, std::vector& views, const cgltf_image& image, const std::string& encoded, const ImageInfo& info, size_t index, const char* output_path, const Settings& settings) +{ + writeImageData(json, views, index, image.uri, "image/ktx2", encoded, output_path, info.kind, settings.texture_embed); } void writeTexture(std::string& json, const cgltf_texture& texture, const ImageInfo* info, cgltf_data* data, const Settings& settings) From e20baef154adb3c1d3d6a560440120dffab6533b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 8 Apr 2024 17:19:34 -0400 Subject: [PATCH 049/581] gltfpack: Use ERR Base64 embedded data for invalid images This prevents errors around missing images in case we can't find the source image or can't encode it. Loading the resulting glTF file will result in a PNG decode error. Unfortunately, files like this are still treated as invalid by glTF spec/validator. --- gltf/write.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gltf/write.cpp b/gltf/write.cpp index 7eae0d6c8e..96794bb800 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -948,7 +948,9 @@ void writeImage(std::string& json, std::vector& views, const cgltf_i void writeImageError(std::string& json, const char* action, size_t index, const char* uri, const char* reason) { - (void)json; + append(json, "\"uri\":\""); + append(json, "data:image/png;base64,ERR/"); + append(json, "\""); fprintf(stderr, "Warning: unable to %s image %d (%s), skipping%s%s%s\n", action, int(index), uri ? uri : "embedded", reason ? " (" : "", reason ? reason : "", reason ? ")" : ""); } From df665ec69ba134713ac057c4f7e65f938970ec73 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 10 Apr 2024 10:32:25 -0700 Subject: [PATCH 050/581] gltfpack: Fixup image mime type between jpeg/png based on headers Some glTF files exported by non-compliant tool chains may use mimeType: image/png but use JPEG images. While these files are invalid, it would be helpful to make an effort to fix this as the mimeType information is fairly redundant. This change uses image header patterns defined in glTF specification to override mime type even if it's defined based on the image contents; this is done in readImage so that all consumers (that are mime type dependent!) get the correct result. --- gltf/image.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/gltf/image.cpp b/gltf/image.cpp index 2b8b6059ad..e45e223aa4 100644 --- a/gltf/image.cpp +++ b/gltf/image.cpp @@ -59,10 +59,22 @@ static bool parseDataUri(const char* uri, std::string& mime_type, std::string& r return false; } +static std::string fixupMimeType(const std::string& data, const std::string& mime_type) +{ + if (mime_type == "image/jpeg" && data.compare(0, 8, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a") == 0) + return "image/png"; + + if (mime_type == "image/png" && data.compare(0, 3, "\xff\xd8\xff") == 0) + return "image/jpeg"; + + return mime_type; +} + bool readImage(const cgltf_image& image, const char* input_path, std::string& data, std::string& mime_type) { if (image.uri && parseDataUri(image.uri, mime_type, data)) { + mime_type = fixupMimeType(data, mime_type); return true; } else if (image.buffer_view && image.buffer_view->buffer->data && image.mime_type) @@ -70,7 +82,9 @@ bool readImage(const cgltf_image& image, const char* input_path, std::string& da const cgltf_buffer_view* view = image.buffer_view; data.assign(static_cast(view->buffer->data) + view->offset, view->size); + mime_type = image.mime_type; + mime_type = fixupMimeType(data, image.mime_type); return true; } else if (image.uri && *image.uri && input_path) @@ -80,9 +94,12 @@ bool readImage(const cgltf_image& image, const char* input_path, std::string& da cgltf_decode_uri(&path[0]); path.resize(strlen(&path[0])); - mime_type = image.mime_type ? image.mime_type : inferMimeType(path.c_str()); + if (!readFile(getFullPath(path.c_str(), input_path).c_str(), data)) + return false; - return readFile(getFullPath(path.c_str(), input_path).c_str(), data); + mime_type = image.mime_type ? image.mime_type : inferMimeType(path.c_str()); + mime_type = fixupMimeType(data, mime_type); + return true; } else { From 1060814598ec0118caf87722f18117f5e97835db Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 12 Apr 2024 09:16:18 -0700 Subject: [PATCH 051/581] gltfpack: Adjust help to more accurately document -vn Tangents don't need as much precision as normals so we're limiting them to 8 bits; this allows higher-than-8 bit normals to preserve specular highlights at a smaller incremental size impact. Fixes #674. --- gltf/gltfpack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 48a0734570..0d9adb2e0c 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -1501,7 +1501,7 @@ int main(int argc, char** argv) fprintf(stderr, "\nVertex precision:\n"); fprintf(stderr, "\t-vp N: use N-bit quantization for positions (default: 14; N should be between 1 and 16)\n"); fprintf(stderr, "\t-vt N: use N-bit quantization for texture coordinates (default: 12; N should be between 1 and 16)\n"); - fprintf(stderr, "\t-vn N: use N-bit quantization for normals and tangents (default: 8; N should be between 1 and 16)\n"); + fprintf(stderr, "\t-vn N: use N-bit quantization for normals (default: 8; N should be between 1 and 16) and tangents (up to 8-bit)\n"); fprintf(stderr, "\t-vc N: use N-bit quantization for colors (default: 8; N should be between 1 and 16)\n"); fprintf(stderr, "\nVertex positions:\n"); fprintf(stderr, "\t-vpi: use integer attributes for positions (default)\n"); From fc52bbde30107b382f0c923d05bfec844c9a2dd9 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 22 Apr 2024 13:59:15 -0700 Subject: [PATCH 052/581] gltfpack: Validate areMaterialsEqual correctness via a self check This improves coverage and will hopefully make sure areMaterialsEqual doesn't have obvious validity bugs where eg we compare two different fields accidentally. --- gltf/material.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gltf/material.cpp b/gltf/material.cpp index 7db0e20f28..0ae2abf93c 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -355,6 +355,8 @@ void mergeMeshMaterials(cgltf_data* data, std::vector& meshes, const Setti if (settings.keep_materials && data->materials[i].name && *data->materials[i].name) continue; + assert(areMaterialsEqual(data->materials[i], data->materials[i], settings)); + for (size_t j = 0; j < i; ++j) { if (settings.keep_materials && data->materials[j].name && *data->materials[j].name) From d7b576a229a45cecdab47dad1b6e7485b754e98d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 22 Apr 2024 14:17:29 -0700 Subject: [PATCH 053/581] gltfpack: Warn when an unsupported extension is required Instead of silently dropping all of the extension's data we now warn when we don't support it and it's listed as required. To simplify maintenance we assume that we don't support any extension that we don't preserve, which should mostly be correct. --- gltf/gltfpack.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 0d9adb2e0c..62ae7b32bf 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -250,6 +250,15 @@ static bool canTransformMesh(const Mesh& mesh) return true; } +static bool isExtensionSupported(const ExtensionInfo* extensions, size_t count, const char* name) +{ + for (size_t i = 0; i < count; ++i) + if (strcmp(extensions[i].name, name) == 0) + return true; + + return false; +} + static void process(cgltf_data* data, const char* input_path, const char* output_path, const char* report_path, std::vector& meshes, std::vector& animations, const Settings& settings, std::string& json, std::string& bin, std::string& fallback, size_t& fallback_size) { if (settings.verbose) @@ -836,6 +845,16 @@ static void process(cgltf_data* data, const char* input_path, const char* output {"EXT_mesh_gpu_instancing", ext_instancing, true}, }; + for (size_t i = 0; i < data->extensions_required_count; ++i) + { + const char* ext = data->extensions_required[i]; + + if (!isExtensionSupported(extensions, sizeof(extensions) / sizeof(extensions[0]), ext)) + { + fprintf(stderr, "Warning: required extension %s is not supported and will be skipped\n", ext); + } + } + writeExtensions(json, extensions, sizeof(extensions) / sizeof(extensions[0])); std::string json_views; From 6d0d7ec01bbc67a464d55c13c08a600b3ba9bc3b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 25 Apr 2024 17:15:42 -0700 Subject: [PATCH 054/581] extern: Update cgltf to 1.14 We were almost caught up but this is adding a missed merge that improves error messages for invalid animations. --- extern/cgltf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extern/cgltf.h b/extern/cgltf.h index d18230a903..17dc0ca5d2 100644 --- a/extern/cgltf.h +++ b/extern/cgltf.h @@ -1,7 +1,7 @@ /** * cgltf - a single-file glTF 2.0 parser written in C99. * - * Version: 1.13 + * Version: 1.14 * * Website: https://github.com/jkuhlmann/cgltf * @@ -1745,7 +1745,7 @@ cgltf_result cgltf_validate(cgltf_data* data) cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1; - CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short); + CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_invalid_gltf); } } From 5c0bb7058bde1037ccea35fa73f18e79d5427d22 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 30 Apr 2024 14:35:28 -0700 Subject: [PATCH 055/581] gltfpack: Refactor writeImage to consolidate encoded image logic Instead of allowing the caller to deal with encoded images we now pass the data to writeImage and allow it to write it. This slightly unifies the error and data write flow and makes it easier to change this logic in one place. --- gltf/gltfpack.cpp | 19 ++++++------------- gltf/gltfpack.h | 4 +--- gltf/write.cpp | 37 +++++++++++++++++++++---------------- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 62ae7b32bf..a01f2070c5 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -484,22 +484,15 @@ static void process(cgltf_data* data, const char* input_path, const char* output { const cgltf_image& image = data->images[i]; + std::string* encoded = (encoded_images.size() && !encoded_images[i].empty()) ? &encoded_images[i] : NULL; + comma(json_images); append(json_images, "{"); - if (encoded_images.size() && !encoded_images[i].empty()) - { - if (encoded_images[i].compare(0, 5, "error") == 0) - writeImageError(json_images, "encode", int(i), image.uri, encoded_images[i].c_str()); - else - writeEncodedImage(json_images, views, image, encoded_images[i], images[i], i, output_path, settings); - - encoded_images[i] = std::string(); // reclaim memory early - } - else - { - writeImage(json_images, views, image, images[i], i, input_path, output_path, settings); - } + writeImage(json_images, views, image, images[i], encoded, i, input_path, output_path, settings); append(json_images, "}"); + + if (encoded) + *encoded = std::string(); // reclaim memory early } for (size_t i = 0; i < data->textures_count; ++i) diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index e22608466e..5e221d673f 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -368,9 +368,7 @@ const char* animationPath(cgltf_animation_path_type type); void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_material& material, const QuantizationPosition* qp, const QuantizationTexture* qt, std::vector& textures); void writeBufferView(std::string& json, BufferView::Kind kind, StreamFormat::Filter filter, size_t count, size_t stride, size_t bin_offset, size_t bin_size, BufferView::Compression compression, size_t compressed_offset, size_t compressed_size); void writeSampler(std::string& json, const cgltf_sampler& sampler); -void writeImage(std::string& json, std::vector& views, const cgltf_image& image, const ImageInfo& info, size_t index, const char* input_path, const char* output_path, const Settings& settings); -void writeImageError(std::string& json, const char* action, size_t index, const char* uri, const char* reason = NULL); -void writeEncodedImage(std::string& json, std::vector& views, const cgltf_image& image, const std::string& encoded, const ImageInfo& info, size_t index, const char* output_path, const Settings& settings); +void writeImage(std::string& json, std::vector& views, const cgltf_image& image, const ImageInfo& info, const std::string* encoded, size_t index, const char* input_path, const char* output_path, const Settings& settings); void writeTexture(std::string& json, const cgltf_texture& texture, const ImageInfo* info, cgltf_data* data, const Settings& settings); void writeMeshAttributes(std::string& json, std::vector& views, std::string& json_accessors, size_t& accr_offset, const Mesh& mesh, int target, const QuantizationPosition& qp, const QuantizationTexture& qt, const Settings& settings); size_t writeMeshIndices(std::vector& views, std::string& json_accessors, size_t& accr_offset, const Mesh& mesh, const Settings& settings); diff --git a/gltf/write.cpp b/gltf/write.cpp index 96794bb800..2ab0d1903e 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -896,6 +896,15 @@ void writeSampler(std::string& json, const cgltf_sampler& sampler) } } +static void writeImageError(std::string& json, const char* action, size_t index, const char* uri, const char* reason) +{ + append(json, "\"uri\":\""); + append(json, "data:image/png;base64,ERR/"); + append(json, "\""); + + fprintf(stderr, "Warning: unable to %s image %d (%s), skipping%s%s%s\n", action, int(index), uri ? uri : "embedded", reason ? " (" : "", reason ? reason : "", reason ? ")" : ""); +} + static void writeImageData(std::string& json, std::vector& views, size_t index, const char* uri, const char* mime_type, const std::string& contents, const char* output_path, TextureKind kind, bool embed) { bool dataUri = uri && strncmp(uri, "data:", 5) == 0; @@ -922,8 +931,18 @@ static void writeImageData(std::string& json, std::vector& views, si } } -void writeImage(std::string& json, std::vector& views, const cgltf_image& image, const ImageInfo& info, size_t index, const char* input_path, const char* output_path, const Settings& settings) +void writeImage(std::string& json, std::vector& views, const cgltf_image& image, const ImageInfo& info, const std::string* encoded, size_t index, const char* input_path, const char* output_path, const Settings& settings) { + if (encoded) + { + // image was pre-encoded via encodeImages (which might have failed!) + if (encoded->compare(0, 5, "error") == 0) + writeImageError(json, "encode", int(index), image.uri, encoded->c_str()); + else + writeImageData(json, views, index, image.uri, "image/ktx2", *encoded, output_path, info.kind, settings.texture_embed); + return; + } + bool dataUri = image.uri && strncmp(image.uri, "data:", 5) == 0; if (image.uri && !dataUri && settings.texture_ref) @@ -939,27 +958,13 @@ void writeImage(std::string& json, std::vector& views, const cgltf_i std::string mime_type; if (!readImage(image, input_path, img_data, mime_type)) { - writeImageError(json, "read", index, image.uri); + writeImageError(json, "read", index, image.uri, NULL); return; } writeImageData(json, views, index, image.uri, mime_type.c_str(), img_data, output_path, info.kind, settings.texture_embed); } -void writeImageError(std::string& json, const char* action, size_t index, const char* uri, const char* reason) -{ - append(json, "\"uri\":\""); - append(json, "data:image/png;base64,ERR/"); - append(json, "\""); - - fprintf(stderr, "Warning: unable to %s image %d (%s), skipping%s%s%s\n", action, int(index), uri ? uri : "embedded", reason ? " (" : "", reason ? reason : "", reason ? ")" : ""); -} - -void writeEncodedImage(std::string& json, std::vector& views, const cgltf_image& image, const std::string& encoded, const ImageInfo& info, size_t index, const char* output_path, const Settings& settings) -{ - writeImageData(json, views, index, image.uri, "image/ktx2", encoded, output_path, info.kind, settings.texture_embed); -} - void writeTexture(std::string& json, const cgltf_texture& texture, const ImageInfo* info, cgltf_data* data, const Settings& settings) { if (texture.image) From ae4d14ec3031d8ab9a077325d546e417ee856115 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 30 Apr 2024 14:43:23 -0700 Subject: [PATCH 056/581] gltfpack: Preserve image names in the output Image names can be useful for identifying images in the output file when embedded images are used, or for custom application processing e.g. for attaching extra images to materials via extra properties. Note that there's redundancy between images and textures; for now we choose to preserve image names and not texture names, as this seems to match conventions used by Blender glTF export. --- gltf/write.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gltf/write.cpp b/gltf/write.cpp index 2ab0d1903e..bb62758cbb 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -933,6 +933,13 @@ static void writeImageData(std::string& json, std::vector& views, si void writeImage(std::string& json, std::vector& views, const cgltf_image& image, const ImageInfo& info, const std::string* encoded, size_t index, const char* input_path, const char* output_path, const Settings& settings) { + if (image.name && *image.name) + { + append(json, "\"name\":\""); + append(json, image.name); + append(json, "\","); + } + if (encoded) { // image was pre-encoded via encodeImages (which might have failed!) From c7bb9c34628f8385fef19f44d556157639393e41 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 13 May 2024 20:42:13 -0500 Subject: [PATCH 057/581] Create USERS.md (#687) This is an initial version of a list of known projects that are using meshoptimizer. It's missing a lot of projects I've been told about and don't remember OTOH, and it's likely missing a *lot* of games that use it that I don't know about. The intent here is to slowly expand this list over time with prominent projects (commercial software or open source software). --- USERS.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 USERS.md diff --git a/USERS.md b/USERS.md new file mode 100644 index 0000000000..cf4af71187 --- /dev/null +++ b/USERS.md @@ -0,0 +1,45 @@ +meshoptimizer is widely used in the games industry as well as in many pipelines for processing 3D content for real-time rendering. This document contains a small selection of projects that rely on meshoptimizer. + +For brevity, the projects listed below are limited to commercial software or open source software that has 100+ stars on GitHub. Please feel free to contribute additions via pull requests. + +# Games + +If you are shipping a game that is using meshoptimizer, listing the library in the credits or documentation would be appreciated! + +- [Alan Wake 2 (2023)](https://www.remedygames.com/games/alan-wake-2) +- [Baldur's Gate 3 (2023)](https://baldursgate3.game/) +- [Cities: Skylines II (2023)](https://www.paradoxinteractive.com/games/cities-skylines-ii/about) +- [Counter-Strike 2 (2023)](https://www.counter-strike.net/cs2) +- [Jagged Alliance 3 (2023)](https://jaggedalliance3.thqnordic.com/) +- [The Legend of Zelda: Tears of the Kingdom (2023)](https://zelda.nintendo.com/tears-of-the-kingdom/) +- [Manifold Garden (2019)](https://manifold.garden) +- [Monaco 2](https://store.steampowered.com/app/1063030/Monaco_2/) +- [Ravenswatch (2023)](https://store.steampowered.com/app/2071280/Ravenswatch/) +- [The Settlers: New Allies (2023)](https://www.ubisoft.com/en-us/game/the-settlers/new-allies) +- [Stranded: Alien Dawn (2023)](https://www.strandedaliendawn.com/en-US) +- [Tunnet (2023)](https://store.steampowered.com/app/2286390/Tunnet/) + +# Engines + +If you are shipping an engine that is using meshoptimizer, listing the library in the documentation would be appreciated! + +- [Bevy](https://bevyengine.org/) +- [The Forge](https://theforge.dev/) +- [Godot](https://godotengine.org/) +- [HypeHype](https://hypehype.com/en) +- [Roblox](https://www.roblox.com/) +- [Unigine](https://unigine.com/) +- [Wonderland Engine](https://wonderlandengine.com/) + +meshoptimizer is also used in [Waymo](https://waymo.com/) internal stack. + +# Web + +meshoptimizer supports various web projects through [meshoptimizer.js](https://www.npmjs.com/package/meshoptimizer). +For projects in the glTF ecosystem, [gltfpack](https://github.com/zeux/meshoptimizer/tree/master/gltf#-gltfpack) is developed alongside meshoptimizer, and `EXT_meshopt_compression` glTF extension is implemented by meshoptimizer.js. + +This list contains a small selection of popular projects in the web ecosystem that use meshoptimizer; see also [a list of projects that depend on meshoptimizer through NPM](https://github.com/zeux/meshoptimizer/network/dependents). + +- [Babylon.js](https://www.babylonjs.com/) +- [CesiumJS](https://cesium.com/platform/cesiumjs/) +- [three.js](https://threejs.org/) From 397724f919b4613d138f2b97a7d4054f28f7ee03 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 13 May 2024 20:20:26 -0700 Subject: [PATCH 058/581] Update USERS.md Add bgfx, filament, glTF-Transform and aframe. --- USERS.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/USERS.md b/USERS.md index cf4af71187..d92b19432e 100644 --- a/USERS.md +++ b/USERS.md @@ -24,12 +24,13 @@ If you are shipping a game that is using meshoptimizer, listing the library in t If you are shipping an engine that is using meshoptimizer, listing the library in the documentation would be appreciated! - [Bevy](https://bevyengine.org/) +- [bgfx](https://github.com/bkaradzic/bgfx) +- [filament](https://github.com/google/filament) - [The Forge](https://theforge.dev/) - [Godot](https://godotengine.org/) - [HypeHype](https://hypehype.com/en) - [Roblox](https://www.roblox.com/) - [Unigine](https://unigine.com/) -- [Wonderland Engine](https://wonderlandengine.com/) meshoptimizer is also used in [Waymo](https://waymo.com/) internal stack. @@ -40,6 +41,9 @@ For projects in the glTF ecosystem, [gltfpack](https://github.com/zeux/meshoptim This list contains a small selection of popular projects in the web ecosystem that use meshoptimizer; see also [a list of projects that depend on meshoptimizer through NPM](https://github.com/zeux/meshoptimizer/network/dependents). +- [aframe](https://aframe.io/) - [Babylon.js](https://www.babylonjs.com/) - [CesiumJS](https://cesium.com/platform/cesiumjs/) - [three.js](https://threejs.org/) +- [glTF-Transform](https://gltf-transform.dev/) +- [Wonderland Engine](https://wonderlandengine.com/) From 5806d7774487b69240cb952e63746ed216847fa1 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 14 May 2024 16:08:29 -0700 Subject: [PATCH 059/581] gltfpack: Fix support for non-triangle meshes This was accidentally broken with cgltf upgrade since it added enum entry for invalid primitive type, and we need to write GL-compatible value. The issue hasn't made it into any numbered release though. --- gltf/gltfpack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index a01f2070c5..fe364367cc 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -578,7 +578,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output if (prim.type != cgltf_primitive_type_triangles) { append(json_meshes, ",\"mode\":"); - append(json_meshes, size_t(prim.type)); + append(json_meshes, size_t(prim.type - cgltf_primitive_type_points)); } if (mesh.targets) { From a90d8bb6cab1578471235a14b809e9428a8a5d80 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 14 May 2024 17:34:20 -0700 Subject: [PATCH 060/581] gltfpack: Use vertex color information for simplification When -sv command line argument is specified, we will use vertex colors (if present) as part of attribute aware simplification to produce better results. For now the intention is to use a single argument to incorporate multiple different types of attributes with fixed weights, in the future we might expose more detailed control via '-sv?' prefix. --- gltf/gltfpack.cpp | 5 +++++ gltf/gltfpack.h | 1 + gltf/mesh.cpp | 14 ++++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index fe364367cc..95f1149a40 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -1324,6 +1324,10 @@ int main(int argc, char** argv) { settings.simplify_lock_borders = true; } + else if (strcmp(arg, "-sv") == 0) + { + settings.simplify_attributes = true; + } #ifndef NDEBUG else if (strcmp(arg, "-sd") == 0 && i + 1 < argc && isdigit(argv[i + 1][0])) { @@ -1509,6 +1513,7 @@ int main(int argc, char** argv) fprintf(stderr, "\nSimplification:\n"); fprintf(stderr, "\t-si R: simplify meshes targeting triangle/point count ratio R (default: 1; R should be between 0 and 1)\n"); fprintf(stderr, "\t-sa: aggressively simplify to the target ratio disregarding quality\n"); + fprintf(stderr, "\t-sv: take vertex attributes into account when simplifying meshes\n"); fprintf(stderr, "\t-slb: lock border vertices during simplification to avoid gaps on connected meshes\n"); fprintf(stderr, "\nVertex precision:\n"); fprintf(stderr, "\t-vp N: use N-bit quantization for positions (default: 14; N should be between 1 and 16)\n"); diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index 5e221d673f..ac87fcdd0a 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -136,6 +136,7 @@ struct Settings float simplify_threshold; bool simplify_aggressive; bool simplify_lock_borders; + bool simplify_attributes; float simplify_debug; int meshlet_debug; diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index f5730c9848..4e45f278c0 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -527,7 +527,7 @@ static Stream* getStream(Mesh& mesh, cgltf_attribute_type type, int index = 0) return NULL; } -static void simplifyMesh(Mesh& mesh, float threshold, bool aggressive, bool lock_borders) +static void simplifyMesh(Mesh& mesh, float threshold, bool attributes, bool aggressive, bool lock_borders) { assert(mesh.type == cgltf_primitive_type_triangles); @@ -548,8 +548,14 @@ static void simplifyMesh(Mesh& mesh, float threshold, bool aggressive, bool lock if (target_index_count < 1) return; + const Stream* colors = getStream(mesh, cgltf_attribute_type_color); + const float colw[3] = {1e-2, 1e-2, 1e-2}; + std::vector indices(mesh.indices.size()); - indices.resize(meshopt_simplify(&indices[0], &mesh.indices[0], mesh.indices.size(), positions->data[0].f, vertex_count, sizeof(Attr), target_index_count, target_error, options)); + if (attributes && colors) + indices.resize(meshopt_simplifyWithAttributes(&indices[0], &mesh.indices[0], mesh.indices.size(), positions->data[0].f, vertex_count, sizeof(Attr), colors->data[0].f, sizeof(Attr), colw, 3, NULL, target_index_count, target_error, options)); + else + indices.resize(meshopt_simplify(&indices[0], &mesh.indices[0], mesh.indices.size(), positions->data[0].f, vertex_count, sizeof(Attr), target_index_count, target_error, options)); mesh.indices.swap(indices); // Note: if the simplifier got stuck, we can try to reindex without normals/tangents and retry @@ -771,7 +777,7 @@ void processMesh(Mesh& mesh, const Settings& settings) reindexMesh(mesh); filterTriangles(mesh); if (settings.simplify_threshold < 1) - simplifyMesh(mesh, settings.simplify_threshold, settings.simplify_aggressive, settings.simplify_lock_borders); + simplifyMesh(mesh, settings.simplify_threshold, settings.simplify_attributes, settings.simplify_aggressive, settings.simplify_lock_borders); optimizeMesh(mesh, settings.compressmore); break; @@ -808,7 +814,7 @@ void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio) meshopt_simplifyDebugLoop = &loop[0]; meshopt_simplifyDebugLoopBack = &loopback[0]; - simplifyMesh(mesh, ratio, /* aggressive= */ false, /* lock_borders= */ false); + simplifyMesh(mesh, ratio, /* attributes= */ false, /* aggressive= */ false, /* lock_borders= */ false); meshopt_simplifyDebugKind = NULL; meshopt_simplifyDebugLoop = NULL; From de6152f8ca95cc20d31831c5240759b2b9eae114 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 14 May 2024 17:39:52 -0700 Subject: [PATCH 061/581] gltfpack: Support -sv together with -sd properly When simplificaiton debugging is enabled we need to try to maintain coherence between debug and render simplification options so that the kind/loops overlaid geometry makes sense. --- gltf/gltfpack.cpp | 2 +- gltf/gltfpack.h | 2 +- gltf/mesh.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 95f1149a40..7918326d2e 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -387,7 +387,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output { Mesh kinds = {}; Mesh loops = {}; - debugSimplify(mesh, kinds, loops, settings.simplify_debug); + debugSimplify(mesh, kinds, loops, settings.simplify_debug, settings.simplify_attributes); debug_meshes.push_back(kinds); debug_meshes.push_back(loops); } diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index ac87fcdd0a..0af349536a 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -303,7 +303,7 @@ cgltf_data* parseGlb(const void* buffer, size_t size, std::vector& meshes, void processAnimation(Animation& animation, const Settings& settings); void processMesh(Mesh& mesh, const Settings& settings); -void debugSimplify(const Mesh& mesh, Mesh& kinds, Mesh& loops, float ratio); +void debugSimplify(const Mesh& mesh, Mesh& kinds, Mesh& loops, float ratio, bool attributes); void debugMeshlets(const Mesh& mesh, Mesh& meshlets, Mesh& bounds, int max_vertices, bool scan); bool compareMeshTargets(const Mesh& lhs, const Mesh& rhs); diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index 4e45f278c0..2f10882941 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -791,7 +791,7 @@ extern MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind; extern MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop; extern MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack; -void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio) +void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio, bool attributes) { Mesh mesh = source; assert(mesh.type == cgltf_primitive_type_triangles); @@ -814,7 +814,7 @@ void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio) meshopt_simplifyDebugLoop = &loop[0]; meshopt_simplifyDebugLoopBack = &loopback[0]; - simplifyMesh(mesh, ratio, /* attributes= */ false, /* aggressive= */ false, /* lock_borders= */ false); + simplifyMesh(mesh, ratio, attributes, /* aggressive= */ false, /* lock_borders= */ false); meshopt_simplifyDebugKind = NULL; meshopt_simplifyDebugLoop = NULL; From 4c692989005701b245da8d152ee7f08676aa08c8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 14 May 2024 17:42:51 -0700 Subject: [PATCH 062/581] gltfpack: Use vertex normals for attribute simplification as fallback When -sv is specified we now use vertex normals if necessary; this improves quality on meshes that don't have colors, although ideally we should give both to the simplifier. --- gltf/mesh.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index 2f10882941..441140810f 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -548,12 +548,14 @@ static void simplifyMesh(Mesh& mesh, float threshold, bool attributes, bool aggr if (target_index_count < 1) return; - const Stream* colors = getStream(mesh, cgltf_attribute_type_color); - const float colw[3] = {1e-2, 1e-2, 1e-2}; + const Stream* attr = getStream(mesh, cgltf_attribute_type_color); + attr = attr ? attr : getStream(mesh, cgltf_attribute_type_normal); + + const float attrw[3] = {1e-2, 1e-2, 1e-2}; std::vector indices(mesh.indices.size()); - if (attributes && colors) - indices.resize(meshopt_simplifyWithAttributes(&indices[0], &mesh.indices[0], mesh.indices.size(), positions->data[0].f, vertex_count, sizeof(Attr), colors->data[0].f, sizeof(Attr), colw, 3, NULL, target_index_count, target_error, options)); + if (attributes && attr) + indices.resize(meshopt_simplifyWithAttributes(&indices[0], &mesh.indices[0], mesh.indices.size(), positions->data[0].f, vertex_count, sizeof(Attr), attr->data[0].f, sizeof(Attr), attrw, 3, NULL, target_index_count, target_error, options)); else indices.resize(meshopt_simplify(&indices[0], &mesh.indices[0], mesh.indices.size(), positions->data[0].f, vertex_count, sizeof(Attr), target_index_count, target_error, options)); mesh.indices.swap(indices); From b15426d245dd112957fe46c5226dfa448bb80b1c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 15 May 2024 09:26:43 -0700 Subject: [PATCH 063/581] gltfpack: Fix MSVC warning wrt precision loss --- gltf/mesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index 441140810f..5307b2dad0 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -551,7 +551,7 @@ static void simplifyMesh(Mesh& mesh, float threshold, bool attributes, bool aggr const Stream* attr = getStream(mesh, cgltf_attribute_type_color); attr = attr ? attr : getStream(mesh, cgltf_attribute_type_normal); - const float attrw[3] = {1e-2, 1e-2, 1e-2}; + const float attrw[3] = {1e-2f, 1e-2f, 1e-2f}; std::vector indices(mesh.indices.size()); if (attributes && attr) From 2fa58328652ee1c0571c735facd1055055a1b837 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 18 May 2024 18:38:43 -0700 Subject: [PATCH 064/581] gltfpack: Allow simplification with target vertex/index count 0 The existing check results in an odd discontinuity: eg when simplifying with ratio 0.1, a 10-triangle mesh will be simplified to a target of 1, but a 9-triangle mesh will be left alone. This becomes more and more problematic for higher simplification ratios, where 0.01 ratio will leave small meshes completely unsimplified. In the future we probably need a more careful simplification schedule; however, this logic is currently extraneous as we will remove empty meshes after processing so we shouldn't need any early outs here, and for triangle simplification the error bounds should preserve detail. --- gltf/mesh.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index 5307b2dad0..3f35ce7ba9 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -545,9 +545,6 @@ static void simplifyMesh(Mesh& mesh, float threshold, bool attributes, bool aggr float target_error_aggressive = 1e-1f; unsigned int options = lock_borders ? meshopt_SimplifyLockBorder : 0; - if (target_index_count < 1) - return; - const Stream* attr = getStream(mesh, cgltf_attribute_type_color); attr = attr ? attr : getStream(mesh, cgltf_attribute_type_normal); @@ -713,13 +710,11 @@ static void simplifyPointMesh(Mesh& mesh, float threshold) size_t target_vertex_count = size_t(double(vertex_count) * threshold); - if (target_vertex_count < 1) - return; - const float color_weight = 1e-2f; std::vector indices(target_vertex_count); - indices.resize(meshopt_simplifyPoints(&indices[0], positions->data[0].f, vertex_count, sizeof(Attr), colors ? colors->data[0].f : NULL, sizeof(Attr), color_weight, target_vertex_count)); + if (target_vertex_count) + indices.resize(meshopt_simplifyPoints(&indices[0], positions->data[0].f, vertex_count, sizeof(Attr), colors ? colors->data[0].f : NULL, sizeof(Attr), color_weight, target_vertex_count)); std::vector scratch(indices.size()); From 27e95681483ba6557f8b041e4d526d74a976f54d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 May 2024 00:27:43 -0700 Subject: [PATCH 065/581] Update build.yml Switch macos build to macos-13 since -latest now means -14. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f537e59d06..84083ff97a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: unix: strategy: matrix: - os: [{name: ubuntu, version: ubuntu-latest}, {name: macos, version: macos-latest}, {name: macos-arm, version: macos-14}] + os: [{name: ubuntu, version: ubuntu-latest}, {name: macos-intel, version: macos-13}, {name: macos-arm, version: macos-14}] name: ${{matrix.os.name}} runs-on: ${{matrix.os.version}} steps: From 984cc3abbbc69855f5d64459d84bb762eea898cd Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 May 2024 17:25:18 -0700 Subject: [PATCH 066/581] gltfpack: Implement initial support for EXT_meshopt_compression inputs When the input file contains EXT_meshopt_compression encoded buffer views we can now decompress them and process the data as usual. This should help with interoperability. If the input uses filters, decompression and recompression may introduce extra precision issues; this is mostly captured by an existing quantization warning though. --- gltf/parsegltf.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 9ebb072437..f511f2a5a3 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -5,6 +5,8 @@ #include #include +#include "../src/meshoptimizer.h" + static const size_t kMaxStreams = 16; static const char* getError(cgltf_result result, cgltf_data* data) @@ -376,7 +378,7 @@ static bool needsDummyBuffers(cgltf_data* data) { cgltf_accessor* accessor = &data->accessors[i]; - if (accessor->buffer_view && accessor->buffer_view->buffer->data == NULL) + if (accessor->buffer_view && accessor->buffer_view->data == NULL && accessor->buffer_view->buffer->data == NULL) return true; if (accessor->is_sparse) @@ -456,6 +458,70 @@ static bool freeUnusedBuffers(cgltf_data* data) return free_bin; } +static cgltf_result decompressMeshopt(cgltf_data* data) +{ + for (size_t i = 0; i < data->buffer_views_count; ++i) + { + if (!data->buffer_views[i].has_meshopt_compression) + continue; + cgltf_meshopt_compression* mc = &data->buffer_views[i].meshopt_compression; + + const unsigned char* source = (const unsigned char*)mc->buffer->data; + if (!source) + return cgltf_result_invalid_gltf; + source += mc->offset; + + void* result = malloc(mc->count * mc->stride); + if (!result) + return cgltf_result_out_of_memory; + + int rc = -1; + + switch (mc->mode) + { + case cgltf_meshopt_compression_mode_attributes: + rc = meshopt_decodeVertexBuffer(result, mc->count, mc->stride, source, mc->size); + break; + + case cgltf_meshopt_compression_mode_triangles: + rc = meshopt_decodeIndexBuffer(result, mc->count, mc->stride, source, mc->size); + break; + + case cgltf_meshopt_compression_mode_indices: + rc = meshopt_decodeIndexSequence(result, mc->count, mc->stride, source, mc->size); + break; + + default: + return cgltf_result_invalid_gltf; + } + + if (rc != 0) + return cgltf_result_io_error; + + switch (mc->filter) + { + case cgltf_meshopt_compression_filter_octahedral: + meshopt_decodeFilterOct(result, mc->count, mc->stride); + break; + + case cgltf_meshopt_compression_filter_quaternion: + meshopt_decodeFilterQuat(result, mc->count, mc->stride); + break; + + case cgltf_meshopt_compression_filter_exponential: + meshopt_decodeFilterExp(result, mc->count, mc->stride); + break; + + default: + break; + } + + data->buffer_views[i].data = result; + } + + return cgltf_result_success; +} + static cgltf_data* parseGltf(cgltf_data* data, cgltf_result result, std::vector& meshes, std::vector& animations, const char** error) { *error = NULL; @@ -464,8 +530,6 @@ static cgltf_data* parseGltf(cgltf_data* data, cgltf_result result, std::vector< *error = getError(result, data); else if (requiresExtension(data, "KHR_draco_mesh_compression")) *error = "file requires Draco mesh compression support"; - else if (requiresExtension(data, "EXT_meshopt_compression")) - *error = "file has already been compressed using gltfpack"; else if (requiresExtension(data, "KHR_texture_basisu")) *error = "file requires BasisU texture support"; else if (requiresExtension(data, "EXT_mesh_gpu_instancing")) @@ -507,6 +571,7 @@ cgltf_data* parseGltf(const char* path, std::vector& meshes, std::vector& meshes, cgltf_result result = cgltf_parse(&options, buffer, size, &data); result = (result == cgltf_result_success) ? cgltf_load_buffers(&options, data, NULL) : result; + result = (result == cgltf_result_success) ? decompressMeshopt(data) : result; result = (result == cgltf_result_success) ? cgltf_validate(data) : result; return parseGltf(data, result, meshes, animations, error); From 2e53fb394d16c79607547d47e0fcc37124690147 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 May 2024 18:24:01 -0700 Subject: [PATCH 067/581] gltfpack: Decompress meshopt buffers after cgltf_validate cgltf_validate checks a host of preconditions that make meshopt decoding safe; the only thing we're missing is index validation after meshopt decoding but that does have an assertion, and could also be done separately in the future. --- gltf/parsegltf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index f511f2a5a3..9b22dd43fd 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -571,8 +571,8 @@ cgltf_data* parseGltf(const char* path, std::vector& meshes, std::vector& meshes, cgltf_result result = cgltf_parse(&options, buffer, size, &data); result = (result == cgltf_result_success) ? cgltf_load_buffers(&options, data, NULL) : result; - result = (result == cgltf_result_success) ? decompressMeshopt(data) : result; result = (result == cgltf_result_success) ? cgltf_validate(data) : result; + result = (result == cgltf_result_success) ? decompressMeshopt(data) : result; return parseGltf(data, result, meshes, animations, error); } From 84a8ebc856b3a83e0866e1df62b9f94c24b953bb Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 May 2024 18:25:36 -0700 Subject: [PATCH 068/581] Update glTF CI to not exclude Meshopt files --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f537e59d06..8b202d99e8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -84,7 +84,7 @@ jobs: - name: test run: find glTF-Sample-Assets -name *.gltf -or -name *.glb | xargs -d '\n' ./gltfpack -cc -test - name: pack - run: find glTF-Sample-Assets -name *.gltf | grep -v 'glTF-Draco\|glTF-KTX\|glTF-Meshopt' | xargs -d '\n' -I '{}' ./gltfpack -i '{}' -o '{}pack.gltf' + run: find glTF-Sample-Assets -name *.gltf | grep -v 'glTF-Draco\|glTF-KTX' | xargs -d '\n' -I '{}' ./gltfpack -i '{}' -o '{}pack.gltf' - name: validate run: | curl -sL $VALIDATOR | tar xJ From 0f6a54ab266ab0335f344f9e83471db996290184 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 May 2024 18:32:21 -0700 Subject: [PATCH 069/581] gltfpack: Add EXT_meshopt_compression to supported extensions --- gltf/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/gltf/README.md b/gltf/README.md index 3319210e00..3e528ebc87 100644 --- a/gltf/README.md +++ b/gltf/README.md @@ -82,6 +82,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th - KHR_materials_volume - KHR_mesh_quantization - KHR_texture_transform +- EXT_meshopt_compression Even if the source file does not use extensions, gltfpack may use some extensions in the output file either by default or when certain options are used: From c839eecaa29358e3cd4cdaff3e2b0c95bf3fa2a6 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 May 2024 19:12:07 -0700 Subject: [PATCH 070/581] gltfpack: Remove unnecessary braces This matches the code style a little better. --- gltf/write.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/gltf/write.cpp b/gltf/write.cpp index bb62758cbb..eb45a11b03 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -666,59 +666,37 @@ void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_materi append(json, "\"extensions\":{"); if (material.has_pbr_specular_glossiness) - { writeMaterialComponent(json, data, material.pbr_specular_glossiness, qt, textures); - } if (material.has_clearcoat) - { writeMaterialComponent(json, data, material.clearcoat, qt, textures); - } if (material.has_transmission) - { writeMaterialComponent(json, data, material.transmission, qt, textures); - } if (material.has_ior) - { writeMaterialComponent(json, data, material.ior); - } if (material.has_specular) - { writeMaterialComponent(json, data, material.specular, qt, textures); - } if (material.has_sheen) - { writeMaterialComponent(json, data, material.sheen, qt, textures); - } if (material.has_volume) - { writeMaterialComponent(json, data, material.volume, qp, qt, textures); - } if (material.has_emissive_strength) - { writeMaterialComponent(json, data, material.emissive_strength); - } if (material.has_iridescence) - { writeMaterialComponent(json, data, material.iridescence, qt, textures); - } if (material.has_anisotropy) - { writeMaterialComponent(json, data, material.anisotropy, qt, textures); - } if (material.has_dispersion) - { writeMaterialComponent(json, data, material.dispersion); - } if (material.unlit) { From b8843d9112d39b20bb3abc0da0e54d8a2b3b23a6 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 May 2024 19:34:21 -0700 Subject: [PATCH 071/581] gltfpack: Fix comment typo Frames are 10ms at 100Hz, not 10Hz. --- gltf/animation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gltf/animation.cpp b/gltf/animation.cpp index 4c8642fdc3..fe9b04dedf 100644 --- a/gltf/animation.cpp +++ b/gltf/animation.cpp @@ -290,7 +290,7 @@ void processAnimation(Animation& animation, const Settings& settings) mint = std::min(mint, maxt); // round the number of frames to nearest but favor the "up" direction - // this means that at 10 Hz resampling, we will try to preserve the last frame <10ms + // this means that at 100 Hz resampling, we will try to preserve the last frame <10ms // but if the last frame is <2ms we favor just removing this data int frames = 1 + int((maxt - mint) * settings.anim_freq + 0.8f); From d314da3333c9799fafffd9c1962c1a91cf9ccbe9 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 22 May 2024 09:18:39 -0700 Subject: [PATCH 072/581] gltfpack: Implement initial support for KHR_texture_basisu inputs When the input file has KHR_texture_basisu extension, we now will preserve the images along with the extension in the output file instead of discarding it. --- gltf/gltfpack.cpp | 4 +++- gltf/material.cpp | 13 ++++++++++--- gltf/parsegltf.cpp | 2 -- gltf/write.cpp | 22 +++++++++++++++------- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 7918326d2e..2db6eff776 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -452,6 +452,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output bool ext_unlit = false; bool ext_instancing = false; bool ext_texture_transform = false; + bool ext_texture_basisu = false; size_t accr_offset = 0; size_t node_offset = 0; @@ -509,6 +510,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output assert(textures[i].remap == int(texture_offset)); texture_offset++; + ext_texture_basisu = ext_texture_basisu || texture.has_basisu; } for (size_t i = 0; i < data->materials_count; ++i) @@ -834,7 +836,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output {"KHR_materials_unlit", ext_unlit, false}, {"KHR_materials_variants", data->variants_count > 0, false}, {"KHR_lights_punctual", data->lights_count > 0, false}, - {"KHR_texture_basisu", !json_textures.empty() && settings.texture_ktx2, true}, + {"KHR_texture_basisu", (!json_textures.empty() && settings.texture_ktx2) || ext_texture_basisu, true}, {"EXT_mesh_gpu_instancing", ext_instancing, true}, }; diff --git a/gltf/material.cpp b/gltf/material.cpp index 0ae2abf93c..83c83a9798 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -435,6 +435,11 @@ bool hasValidTransform(const cgltf_texture_view& view) return false; } +static const cgltf_image* getTextureImage(const cgltf_texture* texture) +{ + return texture ? (texture->has_basisu ? texture->basisu_image : texture->image) : NULL; +} + static void analyzeMaterialTexture(const cgltf_texture_view& view, TextureKind kind, MaterialInfo& mi, cgltf_data* data, std::vector& textures, std::vector& images) { mi.usesTextureTransform |= hasValidTransform(view); @@ -442,9 +447,9 @@ static void analyzeMaterialTexture(const cgltf_texture_view& view, TextureKind k if (view.texture) textures[view.texture - data->textures].keep = true; - if (view.texture && view.texture->image) + if (const cgltf_image* image = getTextureImage(view.texture)) { - ImageInfo& info = images[view.texture->image - data->images]; + ImageInfo& info = images[image - data->images]; mi.textureSetMask |= 1u << view.texcoord; mi.needsTangents |= (kind == TextureKind_Normal); @@ -549,7 +554,9 @@ static bool shouldKeepAlpha(const cgltf_texture_view& color, float alpha, cgltf_ if (alpha != 1.f) return true; - return color.texture && color.texture->image && getChannels(*color.texture->image, images[color.texture->image - data->images], input_path) == 4; + const cgltf_image* image = getTextureImage(color.texture); + + return image && getChannels(*image, images[image - data->images], input_path) == 4; } void optimizeMaterials(cgltf_data* data, const char* input_path, std::vector& images) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 9b22dd43fd..91f0c020fd 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -530,8 +530,6 @@ static cgltf_data* parseGltf(cgltf_data* data, cgltf_result result, std::vector< *error = getError(result, data); else if (requiresExtension(data, "KHR_draco_mesh_compression")) *error = "file requires Draco mesh compression support"; - else if (requiresExtension(data, "KHR_texture_basisu")) - *error = "file requires BasisU texture support"; else if (requiresExtension(data, "EXT_mesh_gpu_instancing")) *error = "file requires mesh instancing support"; else if (needsDummyBuffers(data)) diff --git a/gltf/write.cpp b/gltf/write.cpp index eb45a11b03..e3b7e7d96c 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -952,27 +952,35 @@ void writeImage(std::string& json, std::vector& views, const cgltf_i void writeTexture(std::string& json, const cgltf_texture& texture, const ImageInfo* info, cgltf_data* data, const Settings& settings) { - if (texture.image) + if (texture.sampler) { - if (texture.sampler) - { - append(json, "\"sampler\":"); - append(json, size_t(texture.sampler - data->samplers)); - append(json, ","); - } + append(json, "\"sampler\":"); + append(json, size_t(texture.sampler - data->samplers)); + } + if (texture.image) + { if (info && settings.texture_mode[info->kind] != TextureMode_Raw) { + comma(json); append(json, "\"extensions\":{\"KHR_texture_basisu\":{\"source\":"); append(json, size_t(texture.image - data->images)); append(json, "}}"); } else { + comma(json); append(json, "\"source\":"); append(json, size_t(texture.image - data->images)); } } + else if (texture.has_basisu) + { + comma(json); + append(json, "\"extensions\":{\"KHR_texture_basisu\":{\"source\":"); + append(json, size_t(texture.basisu_image - data->images)); + append(json, "}}"); + } } void writeMeshAttributes(std::string& json, std::vector& views, std::string& json_accessors, size_t& accr_offset, const Mesh& mesh, int target, const QuantizationPosition& qp, const QuantizationTexture& qt, const Settings& settings) From aecdd56444d2984d7fb0027c3b74f6e96e6c73a8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 22 May 2024 09:27:50 -0700 Subject: [PATCH 073/581] gltfpack: Implement transparency analysis for KTX2 images Without this, if the source is a KTX2 image, the material will get its alpha mode removed unconditionally. --- gltf/image.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/gltf/image.cpp b/gltf/image.cpp index e45e223aa4..129938a0e4 100644 --- a/gltf/image.cpp +++ b/gltf/image.cpp @@ -107,12 +107,12 @@ bool readImage(const cgltf_image& image, const char* input_path, std::string& da } } -static int readInt16(const std::string& data, size_t offset) +static int readInt16BE(const std::string& data, size_t offset) { return (unsigned char)data[offset] * 256 + (unsigned char)data[offset + 1]; } -static int readInt32(const std::string& data, size_t offset) +static int readInt32BE(const std::string& data, size_t offset) { return (unsigned((unsigned char)data[offset]) << 24) | (unsigned((unsigned char)data[offset + 1]) << 16) | @@ -120,6 +120,14 @@ static int readInt32(const std::string& data, size_t offset) unsigned((unsigned char)data[offset + 3]); } +static int readInt32LE(const std::string& data, size_t offset) +{ + return unsigned((unsigned char)data[offset]) | + (unsigned((unsigned char)data[offset + 1]) << 8) | + (unsigned((unsigned char)data[offset + 2]) << 16) | + (unsigned((unsigned char)data[offset + 3]) << 24); +} + static bool getDimensionsPng(const std::string& data, int& width, int& height) { if (data.size() < 8 + 8 + 13 + 4) @@ -132,8 +140,8 @@ static bool getDimensionsPng(const std::string& data, int& width, int& height) if (data.compare(12, 4, "IHDR") != 0) return false; - width = readInt32(data, 16); - height = readInt32(data, 20); + width = readInt32BE(data, 16); + height = readInt32BE(data, 20); return true; } @@ -169,13 +177,13 @@ static bool getDimensionsJpeg(const std::string& data, int& width, int& height) if (offset + 10 > data.size()) return false; - width = readInt16(data, offset + 7); - height = readInt16(data, offset + 5); + width = readInt16BE(data, offset + 7); + height = readInt16BE(data, offset + 5); return true; } - offset += 2 + readInt16(data, offset + 2); + offset += 2 + readInt16BE(data, offset + 2); } return false; @@ -202,7 +210,7 @@ static bool hasTransparencyPng(const std::string& data) while (offset + 12 <= data.size()) { - int length = readInt32(data, offset); + int length = readInt32BE(data, offset); if (length < 0) return false; @@ -216,10 +224,49 @@ static bool hasTransparencyPng(const std::string& data) return false; } +static bool hasTransparencyKtx2(const std::string& data) +{ + if (data.size() < 12 + 17 * 4) + return false; + + const char* signature = "\xabKTX 20\xbb\r\n\x1a\n"; + if (data.compare(0, 12, signature) != 0) + return false; + + int dfdOffset = readInt32LE(data, 48); + int dfdLength = readInt32LE(data, 52); + + if (dfdLength < 4 + 24 + 16 || unsigned(dfdOffset) > data.size() || unsigned(dfdLength) > data.size() - dfdOffset) + return false; + + const int KDF_DF_MODEL_ETC1S = 163; + const int KDF_DF_MODEL_UASTC = 166; + const int KHR_DF_CHANNEL_UASTC_RGBA = 3; + const int KHR_DF_CHANNEL_ETC1S_RGB = 0; + const int KHR_DF_CHANNEL_ETC1S_AAA = 15; + + int colorModel = readInt32LE(data, dfdOffset + 12) & 0xff; + int channelType1 = (readInt32LE(data, dfdOffset + 28) >> 24) & 0xf; + int channelType2 = dfdLength >= 4 + 24 + 16 * 2 ? (readInt32LE(data, dfdOffset + 44) >> 24) & 0xf : channelType1; + + if (colorModel == KDF_DF_MODEL_ETC1S) + { + return channelType1 == KHR_DF_CHANNEL_ETC1S_RGB && channelType2 == KHR_DF_CHANNEL_ETC1S_AAA; + } + else if (colorModel == KDF_DF_MODEL_UASTC) + { + return channelType1 == KHR_DF_CHANNEL_UASTC_RGBA; + } + + return false; +} + bool hasAlpha(const std::string& data, const char* mime_type) { if (strcmp(mime_type, "image/png") == 0) return hasTransparencyPng(data); + else if (strcmp(mime_type, "image/ktx2") == 0) + return hasTransparencyKtx2(data); else return false; } From c6d8d373c8cec1068017c00f19d369148fcab403 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 22 May 2024 09:32:24 -0700 Subject: [PATCH 074/581] gltfpack: Fix texture merging when textures only use KTX2 images This is necessary for KTX2 inputs to be fully preserved correctly. --- gltf/material.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gltf/material.cpp b/gltf/material.cpp index 83c83a9798..bfe63b9c51 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -11,6 +11,12 @@ static bool areTexturesEqual(const cgltf_texture& lhs, const cgltf_texture& rhs) if (lhs.sampler != rhs.sampler) return false; + if (lhs.has_basisu != rhs.has_basisu) + return false; + + if (lhs.basisu_image != rhs.basisu_image) + return false; + return true; } From 33d38bfd505bbbbf8533316c46dcd1ca846da738 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 22 May 2024 09:40:42 -0700 Subject: [PATCH 075/581] gltfpack: Skip recompression of KTX2 textures with -tc We now restrict -tc to only handle image/png and image/jpeg mime types, which exludes image/ktx2 and any other future formats that we might support. --- gltf/basisenc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gltf/basisenc.cpp b/gltf/basisenc.cpp index a5deef918a..c108094974 100644 --- a/gltf/basisenc.cpp +++ b/gltf/basisenc.cpp @@ -98,11 +98,13 @@ static const char* prepareEncode(basisu::basis_compressor_params& params, const { std::string img_data; std::string mime_type; - std::string result; if (!readImage(image, input_path, img_data, mime_type)) return "error reading source file"; + if (mime_type != "image/png" && mime_type != "image/jpeg") + return NULL; + int width = 0, height = 0; if (!getDimensions(img_data, mime_type.c_str(), width, height)) return "error parsing image header"; From 0c1a930d8fd4062844e3ab2fab04e30331b6b75c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 22 May 2024 09:50:41 -0700 Subject: [PATCH 076/581] gltfpack: Update README.md We now support KHR_texture_basisu as an input. --- gltf/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/gltf/README.md b/gltf/README.md index 3e528ebc87..a6be164051 100644 --- a/gltf/README.md +++ b/gltf/README.md @@ -81,6 +81,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th - KHR_materials_variants - KHR_materials_volume - KHR_mesh_quantization +- KHR_texture_basisu - KHR_texture_transform - EXT_meshopt_compression From cc7653a46b08441c0fe56c248c1feed8667e3c6f Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 22 May 2024 21:58:30 -0700 Subject: [PATCH 077/581] gltfpack: Adjust handling of textures with redundant images When a texture has both source and encoded image, we prefer to extract various metadata from the source image, but preserve both when writing the texture object. When -tc is used, we encode the source image and leave the pre-compressed image unused (this is a little redundant but requires unused image filtering to fix). --- gltf/material.cpp | 8 +++++++- gltf/write.cpp | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gltf/material.cpp b/gltf/material.cpp index bfe63b9c51..8d017a1871 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -443,7 +443,13 @@ bool hasValidTransform(const cgltf_texture_view& view) static const cgltf_image* getTextureImage(const cgltf_texture* texture) { - return texture ? (texture->has_basisu ? texture->basisu_image : texture->image) : NULL; + if (texture && texture->image) + return texture->image; + + if (texture && texture->has_basisu && texture->basisu_image) + return texture->basisu_image; + + return NULL; } static void analyzeMaterialTexture(const cgltf_texture_view& view, TextureKind kind, MaterialInfo& mi, cgltf_data* data, std::vector& textures, std::vector& images) diff --git a/gltf/write.cpp b/gltf/write.cpp index e3b7e7d96c..abcae6d42c 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -966,6 +966,8 @@ void writeTexture(std::string& json, const cgltf_texture& texture, const ImageIn append(json, "\"extensions\":{\"KHR_texture_basisu\":{\"source\":"); append(json, size_t(texture.image - data->images)); append(json, "}}"); + + return; // skip input basisu image if present, as we replace it with the one we encoded } else { @@ -974,7 +976,8 @@ void writeTexture(std::string& json, const cgltf_texture& texture, const ImageIn append(json, size_t(texture.image - data->images)); } } - else if (texture.has_basisu) + + if (texture.has_basisu && texture.basisu_image) { comma(json); append(json, "\"extensions\":{\"KHR_texture_basisu\":{\"source\":"); From 6a4e1b731dc2afc1fbc95fa08dd48adf5ccf68d2 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 23 May 2024 11:34:48 -0700 Subject: [PATCH 078/581] js: Cache unpack(wasm_*) result for MeshoptDecoder This reduces the cost of useWorkers by ~0.3ms on Firefox: unpack isn't ran often enough to be carefully JIT compiled. This normally doesn't really matter much but unfortunately by introducing useWorkers API we gave people the power to call it on every decode, which is a bad idea but this at least mitigates the cost somewhat. --- js/meshopt_decoder.js | 6 +++--- js/meshopt_decoder.module.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/meshopt_decoder.js b/js/meshopt_decoder.js index 1ddd657855..4091359524 100644 --- a/js/meshopt_decoder.js +++ b/js/meshopt_decoder.js @@ -16,12 +16,12 @@ var MeshoptDecoder = (function() { }; } - var wasm = WebAssembly.validate(detector) ? wasm_simd : wasm_base; + var wasm = WebAssembly.validate(detector) ? unpack(wasm_simd) : unpack(wasm_base); var instance; var ready = - WebAssembly.instantiate(unpack(wasm), {}) + WebAssembly.instantiate(wasm, {}) .then(function(result) { instance = result.instance; instance.exports.__wasm_call_ctors(); @@ -94,7 +94,7 @@ var MeshoptDecoder = (function() { function initWorkers(count) { var source = - "self.ready = WebAssembly.instantiate(new Uint8Array([" + new Uint8Array(unpack(wasm)) + "]), {})" + + "self.ready = WebAssembly.instantiate(new Uint8Array([" + new Uint8Array(wasm) + "]), {})" + ".then(function(result) { result.instance.exports.__wasm_call_ctors(); return result.instance; });" + "self.onmessage = " + workerProcess.name + ";" + decode.toString() + workerProcess.toString(); diff --git a/js/meshopt_decoder.module.js b/js/meshopt_decoder.module.js index 1936748578..aa166b9a96 100644 --- a/js/meshopt_decoder.module.js +++ b/js/meshopt_decoder.module.js @@ -15,12 +15,12 @@ var MeshoptDecoder = (function() { }; } - var wasm = WebAssembly.validate(detector) ? wasm_simd : wasm_base; + var wasm = WebAssembly.validate(detector) ? unpack(wasm_simd) : unpack(wasm_base); var instance; var ready = - WebAssembly.instantiate(unpack(wasm), {}) + WebAssembly.instantiate(wasm, {}) .then(function(result) { instance = result.instance; instance.exports.__wasm_call_ctors(); @@ -93,7 +93,7 @@ var MeshoptDecoder = (function() { function initWorkers(count) { var source = - "self.ready = WebAssembly.instantiate(new Uint8Array([" + new Uint8Array(unpack(wasm)) + "]), {})" + + "self.ready = WebAssembly.instantiate(new Uint8Array([" + new Uint8Array(wasm) + "]), {})" + ".then(function(result) { result.instance.exports.__wasm_call_ctors(); return result.instance; });" + "self.onmessage = " + workerProcess.name + ";" + decode.toString() + workerProcess.toString(); From 16e39876e5a316fc92077dfe5e4f8175a009e892 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 24 May 2024 11:17:19 -0700 Subject: [PATCH 079/581] js: Add a dedicated benchmark for decoding filters We previously only benchmarked decodeVertexBuffer without any filters which made it harder to verify performance after LLVM ugprades; the new benchmark tests decodeVertexBuffer+filter decoding for every available filter type. --- js/benchmark.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/js/benchmark.js b/js/benchmark.js index 5aa06acca7..328658a97b 100644 --- a/js/benchmark.js +++ b/js/benchmark.js @@ -62,6 +62,44 @@ var tests = { return { encodeIndex: t1 - t0, decodeIndex: t2 - t1, bytes: N * 12 }; }, + + decodeGltf: function() { + var N = 1024*1024; + var data = new Uint8Array(N * 16); + + for (var i = 0; i < N * 16; i += 4) + { + data[i + 0] = 0; + data[i + 1] = (i % 16) * 1; + data[i + 2] = (i % 16) * 2; + data[i + 3] = (i % 16) * 8; + } + + var decoded = new Uint8Array(N * 16); + + var filters = [ + { name: "none", filter: "NONE", stride: 16 }, + { name: "oct4", filter: "OCTAHEDRAL", stride: 4 }, + { name: "oct12", filter: "OCTAHEDRAL", stride: 8 }, + { name: "quat12", filter: "QUATERNION", stride: 8 }, + { name: "exp", filter: "EXPONENTIAL", stride: 16 }, + ]; + + var results = { bytes: N * 16 }; + + for (var i = 0; i < filters.length; ++i) { + var f = filters[i]; + var encoded = encoder.encodeVertexBuffer(data, N * 16 / f.stride, f.stride); + + var t0 = performance.now(); + decoder.decodeGltfBuffer(decoded, N * 16 / f.stride, f.stride, encoded, "ATTRIBUTES", f.filter); + var t1 = performance.now(); + + results[f.name] = t1 - t0; + } + + return results; + }, }; Promise.all([encoder.ready, decoder.ready]).then(() => { From 98802b2ead14cd6a78672afbaa981443b4b8fa07 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 24 May 2024 16:53:29 -0700 Subject: [PATCH 080/581] js: Rebuild binaries using clang 18 / WASI SDK 22 meshopt_decoder is now ~2% smaller post-gzip with no performance difference. --- js/meshopt_decoder.js | 6 +++--- js/meshopt_decoder.module.js | 6 +++--- js/meshopt_encoder.js | 4 ++-- js/meshopt_encoder.module.js | 4 ++-- js/meshopt_simplifier.js | 4 ++-- js/meshopt_simplifier.module.js | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/js/meshopt_decoder.js b/js/meshopt_decoder.js index 4091359524..59d6ecd08b 100644 --- a/js/meshopt_decoder.js +++ b/js/meshopt_decoder.js @@ -2,10 +2,10 @@ // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptDecoder = (function() { "use strict"; - // Built with clang version 16.0.0 + // Built with clang version 18.1.2 // Built from meshoptimizer 0.20 - var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;d8Yqdbk:yzeHu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9UhlaicefhodnadTmbalc;WFbGglcjdalcjd6EhDcbhqinaqae9pmeaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxdndndndnalc9WGgmTmbcbhPcehsawcjdfhzaohHinaraH9Rax6midnaraHaxfgo9RcK6mbczhlcbhOinalgic9WfgAawcj;cbffhldndndndndnaHaAco4fRbbaOcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgAco4gCaCciSgCE86bbawcj;cbfaifglcGfaoclfaCfgCRbbaAcl4ciGgXaXciSgXE86bbalcVfaCaXfgCRbbaAcd4ciGgXaXciSgXE86bbalc7faCaXfgCRbbaAciGgAaAciSgAE86bbalctfaCaAfgCRbbaoRbegAco4gXaXciSgXE86bbalc91faCaXfgCRbbaAcl4ciGgXaXciSgXE86bbalc4faCaXfgCRbbaAcd4ciGgXaXciSgXE86bbalc93faCaXfgCRbbaAciGgAaAciSgAE86bbalc94faCaAfgCRbbaoRbdgAco4gXaXciSgXE86bbalc95faCaXfgCRbbaAcl4ciGgXaXciSgXE86bbalc96faCaXfgCRbbaAcd4ciGgXaXciSgXE86bbalc97faCaXfgCRbbaAciGgAaAciSgAE86bbalc98faCaAfgARbbaoRbigoco4gCaCciSgCE86bbalc99faAaCfgARbbaocl4ciGgCaCciSgCE86bbalc9:faAaCfgARbbaocd4ciGgCaCciSgCE86bbalcufaAaCfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgAcl4gCaCcsSgCE86bbawcj;cbfaifglcGfaocwfaCfgCRbbaAcsGgAaAcsSgAE86bbalcVfaCaAfgARbbaoRbegCcl4gXaXcsSgXE86bbalc7faAaXfgARbbaCcsGgCaCcsSgCE86bbalctfaAaCfgARbbaoRbdgCcl4gXaXcsSgXE86bbalc91faAaXfgARbbaCcsGgCaCcsSgCE86bbalc4faAaCfgARbbaoRbigCcl4gXaXcsSgXE86bbalc93faAaXfgARbbaCcsGgCaCcsSgCE86bbalc94faAaCfgARbbaoRblgCcl4gXaXcsSgXE86bbalc95faAaXfgARbbaCcsGgCaCcsSgCE86bbalc96faAaCfgARbbaoRbvgCcl4gXaXcsSgXE86bbalc97faAaXfgARbbaCcsGgCaCcsSgCE86bbalc98faAaCfgARbbaoRbogCcl4gXaXcsSgXE86bbalc99faAaXfgARbbaCcsGgCaCcsSgCE86bbalc9:faAaCfgARbbaoRbrgocl4gCaCcsSgCE86bbalcufaAaCfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaOcdfhOaiczfhlarao9RcL0mekkaiam6miaoTmidnakTmbawaPfRbbhOawcj;cbfhlazhiakhAinaialRbbgHce4cbaHceG9R7aOfgO86bbaiadfhialcefhlaAcufgAmbkkazcefhzaPcefgPad6hsaohHaPad9hmexvkkcbhoasceGmdxikaoaxad2fhXdnakTmbcbhmcehsawcjdfhCinarao9Rax6miaoTmdaoaxfhoawamfRbbhOawcj;cbfhlaChiakhAinaialRbbgHce4cbaHceG9R7aOfgO86bbaiadfhialcefhlaAcufgAmbkaCcefhCamcefgmad6hsamad9hmbkaXhoxikcbhlcehsinarao9Rax6mdaoTmeaoaxfhoalcefglad6hsadal9hmbkaXhoxdkcbhoasceGTmekc9:hoxikabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekcbc99arao9Radcaadca0ESEhokavcj;ebf8Kjjjjbaok;xzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfalaDcu7gPcl4fcsGcitfgsydlhzasydbhHdnaDcsGgDak9pmbavaiaPfcsGcdtfydbaxaDEhsaDThDdndnadcd9hmbabarcetfgPaH87ebaPcdfaz87ebaPclfas87ebxekabarcdtfgPaHBdbaPclfazBdbaPcwfasBdbkaxaDfhxavc;abfalcitfgPasBdbaPazBdlavaicdtfasBdbavc;abfalcefcsGglcitfgPaHBdbaPasBdlaiaDfhialcefhlxdkdndnaDcsSmbamaDfaDc987fcefhmxekaocefhDao8SbbgscFeGhPdndnascu9mmbaDhoxekaocvfhoaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhokaPce4cbaPceG9R7amfhmkdndnadcd9hmbabarcetfgDaH87ebaDcdfaz87ebaDclfam87ebxekabarcdtfgDaHBdbaDclfazBdbaDcwfamBdbkavc;abfalcitfgDamBdbaDazBdlavaicdtfamBdbavc;abfalcefcsGglcitfgDaHBdbaDamBdlaicefhialcefhlxekdnaDcpe0mbaxcefgOavaiaqaDcsGfRbbgscl49RcsGcdtfydbascz6gPEhDavaias9RcsGcdtfydbaOaPfgzascsGgOEhsaOThOdndnadcd9hmbabarcetfgHax87ebaHcdfaD87ebaHclfas87ebxekabarcdtfgHaxBdbaHclfaDBdbaHcwfasBdbkavaicdtfaxBdbavc;abfalcitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfalcefcsGcitfgHasBdbaHaDBdlavaiaPfcsGgicdtfasBdbavc;abfalcdfcsGglcitfgDaxBdbaDasBdlalcefhlaiaOfhiazaOfhxxekaxcbaoRbbgHEgAaDc;:eSgDfhzaHcsGhCaHcl4hXdndnaHcs0mbazcefhOxekazhOavaiaX9RcsGcdtfydbhzkdndnaCmbaOcefhxxekaOhxavaiaH9RcsGcdtfydbhOkdndnaDTmbaocefhDxekaocdfhDao8SbegPcFeGhsdnaPcu9kmbaocofhAascFbGhscrhodninaD8SbbgPcFbGaotasVhsaPcu9kmeaDcefhDaocrfgoc8J9hmbkaAhDxekaDcefhDkasce4cbasceG9R7amfgmhAkdndnaXcsSmbaDhsxekaDcefhsaD8SbbgocFeGhPdnaocu9kmbaDcvfhzaPcFbGhPcrhodninas8SbbgDcFbGaotaPVhPaDcu9kmeascefhsaocrfgoc8J9hmbkazhsxekascefhskaPce4cbaPceG9R7amfgmhzkdndnaCcsSmbashoxekascefhoas8SbbgDcFeGhPdnaDcu9kmbascvfhOaPcFbGhPcrhDdninao8SbbgscFbGaDtaPVhPascu9kmeaocefhoaDcrfgDc8J9hmbkaOhoxekaocefhokaPce4cbaPceG9R7amfgmhOkdndnadcd9hmbabarcetfgDaA87ebaDcdfaz87ebaDclfaO87ebxekabarcdtfgDaABdbaDclfazBdbaDcwfaOBdbkavc;abfalcitfgDazBdbaDaABdlavaicdtfaABdbavc;abfalcefcsGcitfgDaOBdbaDazBdlavaicefgicsGcdtfazBdbavc;abfalcdfcsGcitfgDaABdbaDaOBdlavaiaHcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiarcifgrae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;siliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:Ohkxekcjjjj94hkkabaiavcdfciGfcetfak87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:Ohqxekcjjjj94hqkabaiavcufciGfcetfaq87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohqxekcjjjj94hqkabaiavciGfcetfaq87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; - var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq;b9tqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk;e8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhwcbhDinaDae9pmeawaeaD9RaDawfae6Egqcsfgoc9WGgkci2hxakcethmaocl4cifcd4hPabaDad2fhscbhzdnincbhHalhOcbhAdninaraO9RaP6miavcj;cbfaAak2fhCaOaPfhlcbhidnakc;ab6mbaral9Rc;Gb6mbcbhoinaCaofhidndndndndnaOaoco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklbalczfhlkdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklzalczfhlkdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklaalczfhlkdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalclfaYpQbfaXc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalcwfaYpQbfaXc:q:yjjbfRbbfhlxekaialpbbbpkl8Walczfhlkaoc;abfhiaocjefak0meaihoaral9Rc;Fb0mbkkdndnaiak9pmbaici4hoinaral9RcK6mdaCaifhXdndndndndnaOaico4fRbbaocoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpklbxikaXalpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaXalpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaXalpbbbpklbalczfhlkaocdfhoaiczfgiak6mbkkalTmbaAcd0hHalhOaAcefgAclSmdxekkcbhlaHceGTmdkdnakTmbavcjdfazfhiavazfpbdbhYcbhXinaiavcj;cbfaXfgopblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLaoakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEaoamfpblbg3cep9Ta3aQp9op9Hp9rg3aoaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfhiaXczfgXak6mbkkazclfgzad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfhDc9:hoalmexikkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk;tzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfalaDcu7gPcl4fcsGcitfgsydlhzasydbhHdnaDcsGgDak9pmbavaiaPfcsGcdtfydbaxaDEhsaDThDdndnadcd9hmbabarcetfgPaH87ebaPcdfaz87ebaPclfas87ebxekabarcdtfgPaHBdbaPclfazBdbaPcwfasBdbkaxaDfhxavc;abfalcitfgPasBdbaPazBdlavaicdtfasBdbavc;abfalcefcsGglcitfgPaHBdbaPasBdlaiaDfhialcefhlxdkdndnaDcsSmbamaDfaDc987fcefhmxekaocefhDao8SbbgscFeGhPdndnascu9mmbaDhoxekaocvfhoaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhokaPce4cbaPceG9R7amfhmkdndnadcd9hmbabarcetfgDaH87ebaDcdfaz87ebaDclfam87ebxekabarcdtfgDaHBdbaDclfazBdbaDcwfamBdbkavc;abfalcitfgDamBdbaDazBdlavaicdtfamBdbavc;abfalcefcsGglcitfgDaHBdbaDamBdlaicefhialcefhlxekdnaDcpe0mbaxcefgOavaiaqaDcsGfRbbgscl49RcsGcdtfydbascz6gPEhDavaias9RcsGcdtfydbaOaPfgzascsGgOEhsaOThOdndnadcd9hmbabarcetfgHax87ebaHcdfaD87ebaHclfas87ebxekabarcdtfgHaxBdbaHclfaDBdbaHcwfasBdbkavaicdtfaxBdbavc;abfalcitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfalcefcsGcitfgHasBdbaHaDBdlavaiaPfcsGgicdtfasBdbavc;abfalcdfcsGglcitfgDaxBdbaDasBdlalcefhlaiaOfhiazaOfhxxekaxcbaoRbbgHEgAaDc;:eSgDfhzaHcsGhCaHcl4hXdndnaHcs0mbazcefhOxekazhOavaiaX9RcsGcdtfydbhzkdndnaCmbaOcefhxxekaOhxavaiaH9RcsGcdtfydbhOkdndnaDTmbaocefhDxekaocdfhDao8SbegPcFeGhsdnaPcu9kmbaocofhAascFbGhscrhodninaD8SbbgPcFbGaotasVhsaPcu9kmeaDcefhDaocrfgoc8J9hmbkaAhDxekaDcefhDkasce4cbasceG9R7amfgmhAkdndnaXcsSmbaDhsxekaDcefhsaD8SbbgocFeGhPdnaocu9kmbaDcvfhzaPcFbGhPcrhodninas8SbbgDcFbGaotaPVhPaDcu9kmeascefhsaocrfgoc8J9hmbkazhsxekascefhskaPce4cbaPceG9R7amfgmhzkdndnaCcsSmbashoxekascefhoas8SbbgDcFeGhPdnaDcu9kmbascvfhOaPcFbGhPcrhDdninao8SbbgscFbGaDtaPVhPascu9kmeaocefhoaDcrfgDc8J9hmbkaOhoxekaocefhokaPce4cbaPceG9R7amfgmhOkdndnadcd9hmbabarcetfgDaA87ebaDcdfaz87ebaDclfaO87ebxekabarcdtfgDaABdbaDclfazBdbaDcwfaOBdbkavc;abfalcitfgDazBdbaDaABdlavaicdtfaABdbavc;abfalcefcsGcitfgDaOBdbaDazBdlavaicefgicsGcdtfazBdbavc;abfalcdfcsGcitfgDaABdbaDaOBdlavaiaHcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiarcifgrae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalae9pmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oawaopmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalae9pmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oawaopmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalae9pmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnaval9pmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; + var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; + var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]); var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_decoder.module.js b/js/meshopt_decoder.module.js index aa166b9a96..d5f36710a4 100644 --- a/js/meshopt_decoder.module.js +++ b/js/meshopt_decoder.module.js @@ -1,10 +1,10 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptDecoder = (function() { - // Built with clang version 16.0.0 + // Built with clang version 18.1.2 // Built from meshoptimizer 0.20 - var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;d8Yqdbk:yzeHu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9UhlaicefhodnadTmbalc;WFbGglcjdalcjd6EhDcbhqinaqae9pmeaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxdndndndnalc9WGgmTmbcbhPcehsawcjdfhzaohHinaraH9Rax6midnaraHaxfgo9RcK6mbczhlcbhOinalgic9WfgAawcj;cbffhldndndndndnaHaAco4fRbbaOcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgAco4gCaCciSgCE86bbawcj;cbfaifglcGfaoclfaCfgCRbbaAcl4ciGgXaXciSgXE86bbalcVfaCaXfgCRbbaAcd4ciGgXaXciSgXE86bbalc7faCaXfgCRbbaAciGgAaAciSgAE86bbalctfaCaAfgCRbbaoRbegAco4gXaXciSgXE86bbalc91faCaXfgCRbbaAcl4ciGgXaXciSgXE86bbalc4faCaXfgCRbbaAcd4ciGgXaXciSgXE86bbalc93faCaXfgCRbbaAciGgAaAciSgAE86bbalc94faCaAfgCRbbaoRbdgAco4gXaXciSgXE86bbalc95faCaXfgCRbbaAcl4ciGgXaXciSgXE86bbalc96faCaXfgCRbbaAcd4ciGgXaXciSgXE86bbalc97faCaXfgCRbbaAciGgAaAciSgAE86bbalc98faCaAfgARbbaoRbigoco4gCaCciSgCE86bbalc99faAaCfgARbbaocl4ciGgCaCciSgCE86bbalc9:faAaCfgARbbaocd4ciGgCaCciSgCE86bbalcufaAaCfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgAcl4gCaCcsSgCE86bbawcj;cbfaifglcGfaocwfaCfgCRbbaAcsGgAaAcsSgAE86bbalcVfaCaAfgARbbaoRbegCcl4gXaXcsSgXE86bbalc7faAaXfgARbbaCcsGgCaCcsSgCE86bbalctfaAaCfgARbbaoRbdgCcl4gXaXcsSgXE86bbalc91faAaXfgARbbaCcsGgCaCcsSgCE86bbalc4faAaCfgARbbaoRbigCcl4gXaXcsSgXE86bbalc93faAaXfgARbbaCcsGgCaCcsSgCE86bbalc94faAaCfgARbbaoRblgCcl4gXaXcsSgXE86bbalc95faAaXfgARbbaCcsGgCaCcsSgCE86bbalc96faAaCfgARbbaoRbvgCcl4gXaXcsSgXE86bbalc97faAaXfgARbbaCcsGgCaCcsSgCE86bbalc98faAaCfgARbbaoRbogCcl4gXaXcsSgXE86bbalc99faAaXfgARbbaCcsGgCaCcsSgCE86bbalc9:faAaCfgARbbaoRbrgocl4gCaCcsSgCE86bbalcufaAaCfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaOcdfhOaiczfhlarao9RcL0mekkaiam6miaoTmidnakTmbawaPfRbbhOawcj;cbfhlazhiakhAinaialRbbgHce4cbaHceG9R7aOfgO86bbaiadfhialcefhlaAcufgAmbkkazcefhzaPcefgPad6hsaohHaPad9hmexvkkcbhoasceGmdxikaoaxad2fhXdnakTmbcbhmcehsawcjdfhCinarao9Rax6miaoTmdaoaxfhoawamfRbbhOawcj;cbfhlaChiakhAinaialRbbgHce4cbaHceG9R7aOfgO86bbaiadfhialcefhlaAcufgAmbkaCcefhCamcefgmad6hsamad9hmbkaXhoxikcbhlcehsinarao9Rax6mdaoTmeaoaxfhoalcefglad6hsadal9hmbkaXhoxdkcbhoasceGTmekc9:hoxikabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekcbc99arao9Radcaadca0ESEhokavcj;ebf8Kjjjjbaok;xzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfalaDcu7gPcl4fcsGcitfgsydlhzasydbhHdnaDcsGgDak9pmbavaiaPfcsGcdtfydbaxaDEhsaDThDdndnadcd9hmbabarcetfgPaH87ebaPcdfaz87ebaPclfas87ebxekabarcdtfgPaHBdbaPclfazBdbaPcwfasBdbkaxaDfhxavc;abfalcitfgPasBdbaPazBdlavaicdtfasBdbavc;abfalcefcsGglcitfgPaHBdbaPasBdlaiaDfhialcefhlxdkdndnaDcsSmbamaDfaDc987fcefhmxekaocefhDao8SbbgscFeGhPdndnascu9mmbaDhoxekaocvfhoaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhokaPce4cbaPceG9R7amfhmkdndnadcd9hmbabarcetfgDaH87ebaDcdfaz87ebaDclfam87ebxekabarcdtfgDaHBdbaDclfazBdbaDcwfamBdbkavc;abfalcitfgDamBdbaDazBdlavaicdtfamBdbavc;abfalcefcsGglcitfgDaHBdbaDamBdlaicefhialcefhlxekdnaDcpe0mbaxcefgOavaiaqaDcsGfRbbgscl49RcsGcdtfydbascz6gPEhDavaias9RcsGcdtfydbaOaPfgzascsGgOEhsaOThOdndnadcd9hmbabarcetfgHax87ebaHcdfaD87ebaHclfas87ebxekabarcdtfgHaxBdbaHclfaDBdbaHcwfasBdbkavaicdtfaxBdbavc;abfalcitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfalcefcsGcitfgHasBdbaHaDBdlavaiaPfcsGgicdtfasBdbavc;abfalcdfcsGglcitfgDaxBdbaDasBdlalcefhlaiaOfhiazaOfhxxekaxcbaoRbbgHEgAaDc;:eSgDfhzaHcsGhCaHcl4hXdndnaHcs0mbazcefhOxekazhOavaiaX9RcsGcdtfydbhzkdndnaCmbaOcefhxxekaOhxavaiaH9RcsGcdtfydbhOkdndnaDTmbaocefhDxekaocdfhDao8SbegPcFeGhsdnaPcu9kmbaocofhAascFbGhscrhodninaD8SbbgPcFbGaotasVhsaPcu9kmeaDcefhDaocrfgoc8J9hmbkaAhDxekaDcefhDkasce4cbasceG9R7amfgmhAkdndnaXcsSmbaDhsxekaDcefhsaD8SbbgocFeGhPdnaocu9kmbaDcvfhzaPcFbGhPcrhodninas8SbbgDcFbGaotaPVhPaDcu9kmeascefhsaocrfgoc8J9hmbkazhsxekascefhskaPce4cbaPceG9R7amfgmhzkdndnaCcsSmbashoxekascefhoas8SbbgDcFeGhPdnaDcu9kmbascvfhOaPcFbGhPcrhDdninao8SbbgscFbGaDtaPVhPascu9kmeaocefhoaDcrfgDc8J9hmbkaOhoxekaocefhokaPce4cbaPceG9R7amfgmhOkdndnadcd9hmbabarcetfgDaA87ebaDcdfaz87ebaDclfaO87ebxekabarcdtfgDaABdbaDclfazBdbaDcwfaOBdbkavc;abfalcitfgDazBdbaDaABdlavaicdtfaABdbavc;abfalcefcsGcitfgDaOBdbaDazBdlavaicefgicsGcdtfazBdbavc;abfalcdfcsGcitfgDaABdbaDaOBdlavaiaHcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiarcifgrae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;siliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:Ohkxekcjjjj94hkkabaiavcdfciGfcetfak87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:Ohqxekcjjjj94hqkabaiavcufciGfcetfaq87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohqxekcjjjj94hqkabaiavciGfcetfaq87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; - var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq;b9tqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk;e8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhwcbhDinaDae9pmeawaeaD9RaDawfae6Egqcsfgoc9WGgkci2hxakcethmaocl4cifcd4hPabaDad2fhscbhzdnincbhHalhOcbhAdninaraO9RaP6miavcj;cbfaAak2fhCaOaPfhlcbhidnakc;ab6mbaral9Rc;Gb6mbcbhoinaCaofhidndndndndnaOaoco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklbalczfhlkdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklzalczfhlkdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklaalczfhlkdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalclfaYpQbfaXc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalcwfaYpQbfaXc:q:yjjbfRbbfhlxekaialpbbbpkl8Walczfhlkaoc;abfhiaocjefak0meaihoaral9Rc;Fb0mbkkdndnaiak9pmbaici4hoinaral9RcK6mdaCaifhXdndndndndnaOaico4fRbbaocoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpklbxikaXalpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaXalpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaXalpbbbpklbalczfhlkaocdfhoaiczfgiak6mbkkalTmbaAcd0hHalhOaAcefgAclSmdxekkcbhlaHceGTmdkdnakTmbavcjdfazfhiavazfpbdbhYcbhXinaiavcj;cbfaXfgopblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLaoakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEaoamfpblbg3cep9Ta3aQp9op9Hp9rg3aoaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfhiaXczfgXak6mbkkazclfgzad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfhDc9:hoalmexikkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk;tzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfalaDcu7gPcl4fcsGcitfgsydlhzasydbhHdnaDcsGgDak9pmbavaiaPfcsGcdtfydbaxaDEhsaDThDdndnadcd9hmbabarcetfgPaH87ebaPcdfaz87ebaPclfas87ebxekabarcdtfgPaHBdbaPclfazBdbaPcwfasBdbkaxaDfhxavc;abfalcitfgPasBdbaPazBdlavaicdtfasBdbavc;abfalcefcsGglcitfgPaHBdbaPasBdlaiaDfhialcefhlxdkdndnaDcsSmbamaDfaDc987fcefhmxekaocefhDao8SbbgscFeGhPdndnascu9mmbaDhoxekaocvfhoaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhokaPce4cbaPceG9R7amfhmkdndnadcd9hmbabarcetfgDaH87ebaDcdfaz87ebaDclfam87ebxekabarcdtfgDaHBdbaDclfazBdbaDcwfamBdbkavc;abfalcitfgDamBdbaDazBdlavaicdtfamBdbavc;abfalcefcsGglcitfgDaHBdbaDamBdlaicefhialcefhlxekdnaDcpe0mbaxcefgOavaiaqaDcsGfRbbgscl49RcsGcdtfydbascz6gPEhDavaias9RcsGcdtfydbaOaPfgzascsGgOEhsaOThOdndnadcd9hmbabarcetfgHax87ebaHcdfaD87ebaHclfas87ebxekabarcdtfgHaxBdbaHclfaDBdbaHcwfasBdbkavaicdtfaxBdbavc;abfalcitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfalcefcsGcitfgHasBdbaHaDBdlavaiaPfcsGgicdtfasBdbavc;abfalcdfcsGglcitfgDaxBdbaDasBdlalcefhlaiaOfhiazaOfhxxekaxcbaoRbbgHEgAaDc;:eSgDfhzaHcsGhCaHcl4hXdndnaHcs0mbazcefhOxekazhOavaiaX9RcsGcdtfydbhzkdndnaCmbaOcefhxxekaOhxavaiaH9RcsGcdtfydbhOkdndnaDTmbaocefhDxekaocdfhDao8SbegPcFeGhsdnaPcu9kmbaocofhAascFbGhscrhodninaD8SbbgPcFbGaotasVhsaPcu9kmeaDcefhDaocrfgoc8J9hmbkaAhDxekaDcefhDkasce4cbasceG9R7amfgmhAkdndnaXcsSmbaDhsxekaDcefhsaD8SbbgocFeGhPdnaocu9kmbaDcvfhzaPcFbGhPcrhodninas8SbbgDcFbGaotaPVhPaDcu9kmeascefhsaocrfgoc8J9hmbkazhsxekascefhskaPce4cbaPceG9R7amfgmhzkdndnaCcsSmbashoxekascefhoas8SbbgDcFeGhPdnaDcu9kmbascvfhOaPcFbGhPcrhDdninao8SbbgscFbGaDtaPVhPascu9kmeaocefhoaDcrfgDc8J9hmbkaOhoxekaocefhokaPce4cbaPceG9R7amfgmhOkdndnadcd9hmbabarcetfgDaA87ebaDcdfaz87ebaDclfaO87ebxekabarcdtfgDaABdbaDclfazBdbaDcwfaOBdbkavc;abfalcitfgDazBdbaDaABdlavaicdtfaABdbavc;abfalcefcsGcitfgDaOBdbaDazBdlavaicefgicsGcdtfazBdbavc;abfalcdfcsGcitfgDaABdbaDaOBdlavaiaHcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiarcifgrae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalae9pmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oawaopmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalae9pmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oawaopmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalae9pmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnaval9pmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; + var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; + var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]); var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_encoder.js b/js/meshopt_encoder.js index 221da355bf..7c0f8697db 100644 --- a/js/meshopt_encoder.js +++ b/js/meshopt_encoder.js @@ -2,9 +2,9 @@ // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptEncoder = (function() { "use strict"; - // Built with clang version 16.0.0 + // Built with clang version 18.1.2 // Built from meshoptimizer 0.20 - var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:W;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXqF9qLdbk;3keYu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRb:S:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9UhodndndndndnalTmbaoc;WFbGgecjdaecjd6Ehqcbhkdninakai9pmiaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndndndnaec9WGgsTmbcbhzcehHaPhOawhAxekdnaxTmbcbhAcehHaPhCinaDaAfRbbhXaDcjlfheaChoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkaraw9Ram6miawcbamzNjjjbgeTmiaCcefhCaeamfhwaAcefgAal6hHaAal9hmbxvkkaraw9Ram6mvawcbamzNjjjb8AceheinawgXamfhwalaegoSmldnaraw9Ram6mbaocefheawcbamzNjjjb8AaXmekkaoal6hHxekindnaxTmbaDazfRbbhXaDcjlfheaOhoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkkaraA9Ram6mearaAcbamzNjjjbgKamfgw9RcK6mdcbhYaDcjlfhAinaDcjlfaYfh8AcwhCczhLcehQindndnaQce9hmbcuhoa8ARbbmecbhodninaogecsSmeaecefhoaAaefcefRbbTmbkkcucbaecs6EhoxekaQcetc;:FFFeGhocuaQtcu7cFeGhXcbheinaoaXaAaefRbb9nfhoaecefgecz9hmbkkaoaLaoaL6geEhLaQaCaeEhCaQcetgQcw6mbkdndndndnaCcufPdiebkaKaYco4fgeaeRbbcdciaCclSEaYci4coGtV86bbaCcw9hmeawa8A8Pbb83bbawcwfa8Acwf8Pbb83bbawczfhwxdkaKaYco4fgeaeRbbceaYci4coGtV86bbkdncwaC9TgEmbinawcb86bbawcefhwxbkkcuaCtcu7h8Acbh3aAh5ina5heaEhQcbhoinaeRbbgLa8AcFeGgXaLaX6EaoaCtVhoaecefheaQcufgQmbkawao86bba5aEfh5awcefhwa3aEfg3cz6mbkcbheindnaAaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaYczfgYas9pmbaAczfhAaraw9RcL0mekkaYas6meawTmeaOcefhOazcefgzal6hHawhAazalSmixbkkcbhwaHceGTmexikcbhwaHceGmdkaDaPaxcufal2falz:tjjjb8AaxakfhkawmbkcbhoxokcbhoxvkaiTmekcbhoaraw9Ralcaalca0E6mialc8F9nmexdkcbhoaecufca6mdkawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9Rhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBd:S:kjjbk;rse3u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:C:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgoydbhLaocwfydbhKaoclfydbhYcbh8Adndninalc;abfavcsGcitfgoydlhEdndndnaoydbgoaL9hmbaEaYSmekdnaoaY9hmbaEaK9hmba8Acefh8AxekaoaK9hmeaEaL9hmea8Acdfh8Aka8Ac870mdaXcufhvada8AciGcx2goc:y1jjbfydbaCfcdtfydbhEadaocN1jjbfydbaCfcdtfydbhKadaoc:q1jjbfydbaCfcdtfydbhLcbhodnindnalavcsGcdtfydbaE9hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaEaOSgvaYce9iaYaH9oVgoGh3dndndndndncbcsavEaYaoEgvcs9hmbarce9imbaEaEaAaEcefaASgvEgAcefSmecmcsavEhvkasava8Acdtc;WeGV86bbavcs9hmeaEaA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbkaEhAxdkcPhvasa8AcdtcPV86bbaEhAkavTmbavaH9imekalaXcdtfaEBdbaXcefcsGhXkaOa3fhOalc;abfaQcitfgvaKBdlavaEBdbalc;abfaQcefcsGgvcitfgoaEBdlaoaLBdbavcefhoxikavcufhva8Aclfg8Ac;ab9hmbkkdnadceaKaOScetaYaOSEcx2gvc:q1jjbfydbaCfcdtfydbgLTadavcN1jjbfydbaCfcdtfydbg8AceSGadavc:y1jjbfydbaCfcdtfydbgYcdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhKxdkcuhKaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydbaY9hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaLaOSg8Efh3dndnaKcm0mbaKcefhKxekcbcsa8Aa3SgvEhKa3avfh3kdndnaEcm0mbaEcefhExekcbcsaYa3SgvEhEa3avfh3kc9:cua8EEh8FaEaKcltVhocbhvdndndninavcj1jjbfRbbaocFeGSmeavcefgvcz9hmbxdkka5aLaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeao86bbaecefhekdna8EmbaLaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaLhAkdnaKcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmbaYaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaYhAkalaXcdtfaLBdbaXcefcsGhvdndnaKPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfaYBdbavcefcsGhvkalc;abfaQcitfgoaLBdlaoa8ABdbalc;abfaQcefcsGcitfgoa8ABdlaoaYBdbalc;abfaQcdfcsGcitfgoaYBdlaoaLBdbaQcifhoavhXa3hOkascefhsaocsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:C:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:C:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:dvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhralcxfIdbhqdndnakJbbbb9GTmbaxhkxekJbbjZar:l:tgkak:maxJbbbb9GEhkJbbjZax:l:tgxax:marJbbbb9GEhrkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEavNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohmxekcjjjj94hmkdndnakJbbj:;akJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;akJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;klld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicdfciGcdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:Hvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6mearcearce0EhwaohDinaDc:CuBdbaDclfhDawcufgwmbkaeTmiadcl6mdarcearce0EhqarcdthkalhxcbhminaohDaxhwaqhPinaDaDydbgsawydbgzcL4cFeGc:cufcbazEgzasaz9kEBdbawclfhwaDclfhDaPcufgPmbkaxakfhxamcefgmae9hmbkkaeTmdxekaeTmekavcb9hadcl6gqVhHarcearce0Ehkarcdthrceai9Rhmcbhdindndndnavce9hmbaqmdc:CuhwalhDakhPinawaDydbgscL4cFeGc:cufcbasEgsawas9kEhwaDclfhDaPcufgPmbxdkkc:CuhwaHmbaohDalhPakhsinaDaPydbgzcL4cFeGgxc8Aaxc8A9kEc:cufcbazEBdbaPclfhPaDclfhDascufgsmbkkaqmbcbhDakhsinawhPdnavceSmbaoaDfydbhPkdndnalaDfIdbgOcjjj;8iamaPfgPcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohzxekcjjjj94hzkabaDfazcFFFrGaPcKtVBdbaDclfhDascufgsmbkkabarfhbalarfhladcefgdae9hmbkkaocjdf8Kjjjjbk;4qdAui998Jjjjjbc:Gd9Rgv8Kjjjjbavc:4efcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgoadcFFFFi0Ecbyd:K:kjjbHjjjjbbgeBd:4eavceBd:ydaeabaoz:tjjjb8Akavc:OefcwfcbBdbav9cb83i:Oeavc:Oefaeadaiavc:4efz:njjjbavyd:Oehradci9Ugwcbyd:K:kjjbHjjjjbbhoavc:4efavyd:ydgDcdtfaoBdbavaDcefgqBd:ydaocbawzNjjjbhkavc:4efaqcdtfcuaicdtaicFFFFi0Ecbyd:K:kjjbHjjjjbbgxBdbavaDcdfgmBd:ydarhoaxhqinaqalIdbalaoydbgPcwaPcw6Ecdtfc;ebfIdbMUdbaoclfhoaqclfhqaicufgimbkavc:4efamcdtfcuawcdtadcFFFF970Ecbyd:K:kjjbHjjjjbbgmBdbavaDcifBd:yddnadci6mbawceawce0EhiaehoamhqinaqaxaoydbcdtfIdbaxaoclfydbcdtfIdbMaxaocwfydbcdtfIdbMUdbaocxfhoaqclfhqaicufgimbkkavc;qbfhsavhoavyd:Sehzavyd:WehHcbhPcbhqcbhOcehAinaohCcihXaeaqci2gQcdtfgocwfydbhdaoydbhDabaOcx2fgiclfaoclfydbgLBdbaiaDBdbaicwfadBdbakaqfce86bbasadBdwasaLBdlasaDBdbamaqcdtfcbBdbdnaPTmbcihXaChiinasaXcdtfaiydbgoBdbaXaoad9haoaD9haoaL9hGGfhXaiclfhiaPcufgPmbkkaOcefhOcbhPinaHazaeaPaQfcdtfydbcdtgifydbcdtfgLhoaraifgDydbgdhidnadTmbdninaoydbaqSmeaoclfhoaicufgiTmdxbkkaoadcdtaLfc98fydbBdbaDaDydbcufBdbkaPcefgPci9hmbkdndndnaXTmbcuhqJbbbbhKcbhDavyd:SehLavyd:WehQindndnarasaDcdtfydbcdtgPfydbgombaDcefhDxekaDcs0hiaxaPfgdIdbhYadalcbaDcefgDaiEcdtfIdbalaocwaocw6Ecdtfc;ebfIdbMg8AUdba8AaY:th8AaocdthiaQaLaPfydbcdtfhoinamaoydbgPcdtfgda8AadIdbMgYUdbaYaKaKaY9DgdEhKaPaqadEhqaoclfhoaic98fgimbkkaDaX9hmbkaqcu9hmekaAaw9pmeindnakaAfRbbmbaAhqxdkawaAcefgA9hmbxdkkaXczaXcz6EhPashoaChsaqcu9hmekkavyd:ydhokaocdtavc:4effc98fhqdninaoTmeaqydbcbyd:G:kjjbH:bjjjbbaqc98fhqaocufhoxbkkavc:Gdf8Kjjjjbk;UlevucuaicdtgvaicFFFFi0Egocbyd:K:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhwdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbawceawce0EhDabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;:kivuo99lu8Jjjjjbcj;Hb9Rgl8Kjjjjbcbhvalc1;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:K:kjjbHjjjjbbgrBd19GalceBd;O9Galcwfcbyd:m:kjjbBdbalcb8Pd:e:kjjb83ibalc;W;Gbfcwfcbyd:y:kjjbBdbalcb8Pd:q:kjjb83i;W9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;W;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;49GhDalIdlhkalId;09GhxalIdbhmalId;W9GhPkdndnadTmbJbbbbJbbjZaPam:tJbbbb:xgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhialaocbyd:K:kjjbHjjjjbbgzBd:m9GdnadTmbabhHinaHaiBdbaHclfhHadaicefgi9hmbkadTmbabhiadhHinalaraiydbgecdtfydbcFrGcx2fgvavydbgvcefBdbazavcdtfaeBdbaiclfhiaHcufgHmbkazhiadhHinalaraiydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaiclfhiaHcufgHmbkabhiadhHinalaraiydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwazavcdtfaeBdbaiclfhiaHcufgHmbkadTmbcbhiinabazydbcdtfaiBdbazclfhzadaicefgi9hmbkkclhidninaic98Smealc1;Gbfaifydbcbyd:G:kjjbH:bjjjbbaic98fhixbkkalcj;Hbf8Kjjjjbk9teiucbcbyd:O:kjjbgeabcifc98GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:O:kjjbgeabcrfc94GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:O:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:O:kjjbfgdBd:O:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:6ddbcjwk:Cdb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:FFuuFFuuFFuuFFuFFFuFFFuFbc:Cqkzebbbebbbdbbb8WWbb"; + var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_encoder.module.js b/js/meshopt_encoder.module.js index 0ce51b959d..c2b7efd88d 100644 --- a/js/meshopt_encoder.module.js +++ b/js/meshopt_encoder.module.js @@ -1,9 +1,9 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptEncoder = (function() { - // Built with clang version 16.0.0 + // Built with clang version 18.1.2 // Built from meshoptimizer 0.20 - var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:W;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXqF9qLdbk;3keYu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRb:S:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9UhodndndndndnalTmbaoc;WFbGgecjdaecjd6Ehqcbhkdninakai9pmiaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndndndnaec9WGgsTmbcbhzcehHaPhOawhAxekdnaxTmbcbhAcehHaPhCinaDaAfRbbhXaDcjlfheaChoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkaraw9Ram6miawcbamzNjjjbgeTmiaCcefhCaeamfhwaAcefgAal6hHaAal9hmbxvkkaraw9Ram6mvawcbamzNjjjb8AceheinawgXamfhwalaegoSmldnaraw9Ram6mbaocefheawcbamzNjjjb8AaXmekkaoal6hHxekindnaxTmbaDazfRbbhXaDcjlfheaOhoaxhQinaeaoRbbgLaX9RgXcetaX;acr4786bbaoalfhoaecefheaLhXaQcufgQmbkkaraA9Ram6mearaAcbamzNjjjbgKamfgw9RcK6mdcbhYaDcjlfhAinaDcjlfaYfh8AcwhCczhLcehQindndnaQce9hmbcuhoa8ARbbmecbhodninaogecsSmeaecefhoaAaefcefRbbTmbkkcucbaecs6EhoxekaQcetc;:FFFeGhocuaQtcu7cFeGhXcbheinaoaXaAaefRbb9nfhoaecefgecz9hmbkkaoaLaoaL6geEhLaQaCaeEhCaQcetgQcw6mbkdndndndnaCcufPdiebkaKaYco4fgeaeRbbcdciaCclSEaYci4coGtV86bbaCcw9hmeawa8A8Pbb83bbawcwfa8Acwf8Pbb83bbawczfhwxdkaKaYco4fgeaeRbbceaYci4coGtV86bbkdncwaC9TgEmbinawcb86bbawcefhwxbkkcuaCtcu7h8Acbh3aAh5ina5heaEhQcbhoinaeRbbgLa8AcFeGgXaLaX6EaoaCtVhoaecefheaQcufgQmbkawao86bba5aEfh5awcefhwa3aEfg3cz6mbkcbheindnaAaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaYczfgYas9pmbaAczfhAaraw9RcL0mekkaYas6meawTmeaOcefhOazcefgzal6hHawhAazalSmixbkkcbhwaHceGTmexikcbhwaHceGmdkaDaPaxcufal2falz:tjjjb8AaxakfhkawmbkcbhoxokcbhoxvkaiTmekcbhoaraw9Ralcaalca0E6mialc8F9nmexdkcbhoaecufca6mdkawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9Rhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBd:S:kjjbk;rse3u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:C:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgoydbhLaocwfydbhKaoclfydbhYcbh8Adndninalc;abfavcsGcitfgoydlhEdndndnaoydbgoaL9hmbaEaYSmekdnaoaY9hmbaEaK9hmba8Acefh8AxekaoaK9hmeaEaL9hmea8Acdfh8Aka8Ac870mdaXcufhvada8AciGcx2goc:y1jjbfydbaCfcdtfydbhEadaocN1jjbfydbaCfcdtfydbhKadaoc:q1jjbfydbaCfcdtfydbhLcbhodnindnalavcsGcdtfydbaE9hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaEaOSgvaYce9iaYaH9oVgoGh3dndndndndncbcsavEaYaoEgvcs9hmbarce9imbaEaEaAaEcefaASgvEgAcefSmecmcsavEhvkasava8Acdtc;WeGV86bbavcs9hmeaEaA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbkaEhAxdkcPhvasa8AcdtcPV86bbaEhAkavTmbavaH9imekalaXcdtfaEBdbaXcefcsGhXkaOa3fhOalc;abfaQcitfgvaKBdlavaEBdbalc;abfaQcefcsGgvcitfgoaEBdlaoaLBdbavcefhoxikavcufhva8Aclfg8Ac;ab9hmbkkdnadceaKaOScetaYaOSEcx2gvc:q1jjbfydbaCfcdtfydbgLTadavcN1jjbfydbaCfcdtfydbg8AceSGadavc:y1jjbfydbaCfcdtfydbgYcdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhKxdkcuhKaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydbaY9hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaLaOSg8Efh3dndnaKcm0mbaKcefhKxekcbcsa8Aa3SgvEhKa3avfh3kdndnaEcm0mbaEcefhExekcbcsaYa3SgvEhEa3avfh3kc9:cua8EEh8FaEaKcltVhocbhvdndndninavcj1jjbfRbbaocFeGSmeavcefgvcz9hmbxdkka5aLaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeao86bbaecefhekdna8EmbaLaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaLhAkdnaKcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmbaYaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaYhAkalaXcdtfaLBdbaXcefcsGhvdndnaKPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfaYBdbavcefcsGhvkalc;abfaQcitfgoaLBdlaoa8ABdbalc;abfaQcefcsGcitfgoa8ABdlaoaYBdbalc;abfaQcdfcsGcitfgoaYBdlaoaLBdbaQcifhoavhXa3hOkascefhsaocsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:C:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:C:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:dvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhralcxfIdbhqdndnakJbbbb9GTmbaxhkxekJbbjZar:l:tgkak:maxJbbbb9GEhkJbbjZax:l:tgxax:marJbbbb9GEhrkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEavNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohmxekcjjjj94hmkdndnakJbbj:;akJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;akJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;klld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicdfciGcdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:Hvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6mearcearce0EhwaohDinaDc:CuBdbaDclfhDawcufgwmbkaeTmiadcl6mdarcearce0EhqarcdthkalhxcbhminaohDaxhwaqhPinaDaDydbgsawydbgzcL4cFeGc:cufcbazEgzasaz9kEBdbawclfhwaDclfhDaPcufgPmbkaxakfhxamcefgmae9hmbkkaeTmdxekaeTmekavcb9hadcl6gqVhHarcearce0Ehkarcdthrceai9Rhmcbhdindndndnavce9hmbaqmdc:CuhwalhDakhPinawaDydbgscL4cFeGc:cufcbasEgsawas9kEhwaDclfhDaPcufgPmbxdkkc:CuhwaHmbaohDalhPakhsinaDaPydbgzcL4cFeGgxc8Aaxc8A9kEc:cufcbazEBdbaPclfhPaDclfhDascufgsmbkkaqmbcbhDakhsinawhPdnavceSmbaoaDfydbhPkdndnalaDfIdbgOcjjj;8iamaPfgPcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohzxekcjjjj94hzkabaDfazcFFFrGaPcKtVBdbaDclfhDascufgsmbkkabarfhbalarfhladcefgdae9hmbkkaocjdf8Kjjjjbk;4qdAui998Jjjjjbc:Gd9Rgv8Kjjjjbavc:4efcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgoadcFFFFi0Ecbyd:K:kjjbHjjjjbbgeBd:4eavceBd:ydaeabaoz:tjjjb8Akavc:OefcwfcbBdbav9cb83i:Oeavc:Oefaeadaiavc:4efz:njjjbavyd:Oehradci9Ugwcbyd:K:kjjbHjjjjbbhoavc:4efavyd:ydgDcdtfaoBdbavaDcefgqBd:ydaocbawzNjjjbhkavc:4efaqcdtfcuaicdtaicFFFFi0Ecbyd:K:kjjbHjjjjbbgxBdbavaDcdfgmBd:ydarhoaxhqinaqalIdbalaoydbgPcwaPcw6Ecdtfc;ebfIdbMUdbaoclfhoaqclfhqaicufgimbkavc:4efamcdtfcuawcdtadcFFFF970Ecbyd:K:kjjbHjjjjbbgmBdbavaDcifBd:yddnadci6mbawceawce0EhiaehoamhqinaqaxaoydbcdtfIdbaxaoclfydbcdtfIdbMaxaocwfydbcdtfIdbMUdbaocxfhoaqclfhqaicufgimbkkavc;qbfhsavhoavyd:Sehzavyd:WehHcbhPcbhqcbhOcehAinaohCcihXaeaqci2gQcdtfgocwfydbhdaoydbhDabaOcx2fgiclfaoclfydbgLBdbaiaDBdbaicwfadBdbakaqfce86bbasadBdwasaLBdlasaDBdbamaqcdtfcbBdbdnaPTmbcihXaChiinasaXcdtfaiydbgoBdbaXaoad9haoaD9haoaL9hGGfhXaiclfhiaPcufgPmbkkaOcefhOcbhPinaHazaeaPaQfcdtfydbcdtgifydbcdtfgLhoaraifgDydbgdhidnadTmbdninaoydbaqSmeaoclfhoaicufgiTmdxbkkaoadcdtaLfc98fydbBdbaDaDydbcufBdbkaPcefgPci9hmbkdndndnaXTmbcuhqJbbbbhKcbhDavyd:SehLavyd:WehQindndnarasaDcdtfydbcdtgPfydbgombaDcefhDxekaDcs0hiaxaPfgdIdbhYadalcbaDcefgDaiEcdtfIdbalaocwaocw6Ecdtfc;ebfIdbMg8AUdba8AaY:th8AaocdthiaQaLaPfydbcdtfhoinamaoydbgPcdtfgda8AadIdbMgYUdbaYaKaKaY9DgdEhKaPaqadEhqaoclfhoaic98fgimbkkaDaX9hmbkaqcu9hmekaAaw9pmeindnakaAfRbbmbaAhqxdkawaAcefgA9hmbxdkkaXczaXcz6EhPashoaChsaqcu9hmekkavyd:ydhokaocdtavc:4effc98fhqdninaoTmeaqydbcbyd:G:kjjbH:bjjjbbaqc98fhqaocufhoxbkkavc:Gdf8Kjjjjbk;UlevucuaicdtgvaicFFFFi0Egocbyd:K:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:K:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhwdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbawceawce0EhDabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;:kivuo99lu8Jjjjjbcj;Hb9Rgl8Kjjjjbcbhvalc1;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:K:kjjbHjjjjbbgrBd19GalceBd;O9Galcwfcbyd:m:kjjbBdbalcb8Pd:e:kjjb83ibalc;W;Gbfcwfcbyd:y:kjjbBdbalcb8Pd:q:kjjb83i;W9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;W;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;49GhDalIdlhkalId;09GhxalIdbhmalId;W9GhPkdndnadTmbJbbbbJbbjZaPam:tJbbbb:xgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhialaocbyd:K:kjjbHjjjjbbgzBd:m9GdnadTmbabhHinaHaiBdbaHclfhHadaicefgi9hmbkadTmbabhiadhHinalaraiydbgecdtfydbcFrGcx2fgvavydbgvcefBdbazavcdtfaeBdbaiclfhiaHcufgHmbkazhiadhHinalaraiydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaiclfhiaHcufgHmbkabhiadhHinalaraiydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwazavcdtfaeBdbaiclfhiaHcufgHmbkadTmbcbhiinabazydbcdtfaiBdbazclfhzadaicefgi9hmbkkclhidninaic98Smealc1;Gbfaifydbcbyd:G:kjjbH:bjjjbbaic98fhixbkkalcj;Hbf8Kjjjjbk9teiucbcbyd:O:kjjbgeabcifc98GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:O:kjjbgeabcrfc94GfgbBd:O:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:O:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:O:kjjbfgdBd:O:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:6ddbcjwk:Cdb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:FFuuFFuuFFuuFFuFFFuFFFuFbc:Cqkzebbbebbbdbbb8WWbb"; + var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 9c9a12fc09..3daeb3808f 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -2,9 +2,9 @@ // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptSimplifier = (function() { "use strict"; - // Built with clang version 16.0.0 + // Built with clang version 18.1.2 // Built from meshoptimizer 0.20 - var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;H9Usdbk;N6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascwfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd1:jjjbHjjjjbbgHBdwasceBd9OasaHBdbascuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgOBdxascdBd9OasaOBdlasaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd1:jjjbHjjjjbbgXBdzasciBd9OasaCcbyd1:jjjbHjjjjbbgQBdCasclBd9Oalcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd1:jjjbHjjjjbbgLBdKascvBd9OaLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd:m:jjjbH:bjjjbbasclBd9Oasalcbyd1:jjjbHjjjjbbg3BdKascvBd9OasaCcbyd1:jjjbHjjjjbbgzBd3ascoBd9OasaCcbyd1:jjjbHjjjjbbgKBdaascrBd9OazcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Kascwfasyd9Ogzcdtfa8KBdbasazcefgABd9Oa8Kaialavz:djjjbdndnaDmbcbhvxekcbh8EascwfaAcdtfcuaDal2gKcdtaKcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbasazcdfgABd9OalTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascwfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd1:jjjbHjjjjbbgKBdbasaAcefg5Bd9OaKcbazz:ljjjbh8FdndndnaDTmbascwfa5cdtfaLcbyd1:jjjbHjjjjbbgoBdbasaAcdfgKBd9Oaocbazz:ljjjb8AascwfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd1:jjjbHjjjjbbgqBdbasaAcifBd9OaqcbaKz:ljjjb8AadmexdkcbhocbhqadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Eaeh8AincbhKina3aeaKc:G1jjbfydba8EfcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:W1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekJbbacJbbjZazceSEh8RaEceShAa8KaeaKc:K1jjbfydba8Efcdtfydbcx2fhzdna8KaLcx2fgEIdwa8Ka5cx2fgYIdwg8P:tgIaINaEIdbaYIdbg8U:tgyayNaEIdlaYIdlg8S:tgRaRNMM:rg8NJbbbb9ETmbaIa8N:vhIaRa8N:vhRaya8N:vhykJbbaca8RaAEh8XdnazIdwa8P:tg8RaIa8RaINazIdba8U:tg8YayNaRazIdla8S:tg8WNMMg8VN:tg8Ra8RNa8Yaya8VN:tgIaINa8WaRa8VN:tgyayNMM:rgRJbbbb9ETmba8RaR:vh8RayaR:vhyaIaR:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNgRaINNg8VazIdbMUdbazayaRayNg8XNg8YazIdlMUdlaza8RaRa8RNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIaRa8Ra8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3aza8Ra8NNg8RazIdaMUdaaza8Na8PNg8NazId8KMUd8KazaRazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3aza8RazIdaMUdaaza8NazId8KMUd8KazaRazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Ecifg8Ead6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tg8Ra8RNaKIdlaLIdlg80:tgRaRNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNa8RazIdba8Z:tg8PNaRazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNaRaIN:ta8VNh83a8YaRNa8SaIN:ta8VNhUa8Xa8PNa8RaIN:ta8VNh85a8Ya8RNa8PaIN:ta8VNh86a8Ra8SNa8PaRN:tgIaINaRa8NNa8SayN:tgIaINaya8PNa8Na8RN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tgRNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUaRNa83a8PNMg8RNUdbazaIa86aRNa85a8PNMgRNUdbazcxfaIa87ayNa88a8RNa8Na89aRNMMMg8NNUdbaIaya8RNNa8YMh8YaIayaRNNa8WMh8WaIa8RaRNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIa8Ra8NNNa8VMh8VaIaRa8NNNa8XMh8XaIayayNNa80Mh80aIa8Ra8RNNa8:Mh8:aIaRaRNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaoaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydbhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Mascwfasyd9Ogzcdtfa8MBdbasazcefgKBd9OascwfaKcdtfcuamcdtamcFFFFi0Ecbyd1:jjjbHjjjjbbgwBdbasazcdfgKBd9OascwfaKcdtfaCcbyd1:jjjbHjjjjbbgOBdbasazcifgKBd9OascwfaKcdtfalcbyd1:jjjbHjjjjbbgcBdbasazclfBd9OJbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasabadggalaXz:cjjjbabhAcbhHcbhYincbhzindnaXaAazfydbgLcdtg8AfydbgEaXabazc;m1jjbfydbaYfcdtfydbgKcdtfydbg8ESmba3aKfRbbgecv2a3aLfRbbg5fc;G1jjbfRbbg8La5cv2aefg8Jc;G1jjbfRbbgiVcFeGTmbdna8Jc:W1jjbfRbbTmba8EaE0mekdna5ae9hmba5cufcFeGce0mbaaa8AfydbaK9hmeka8MaHcx2fg5aKaLaicFeGgEEBdla5aLaKaEEBdba5aEa8LGcb9hBdwaHcefhHkazclfgzcx9hmbkdnaYcifgYag9pmbaAcxfhAaHcifam9nmekkdnaHmbaghdxikcbheinJbbbbJbbjZa8FaXa8Maecx2fg5ydlgEa5ydbg8Ea5ydwgKEgYcdtfydbg8Lc8S2gifgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEg8Acx2fgKIdwgRNazIdzaKIdbg8NNazIdaMgIaIMMaRNazIdlaKIdlg8PNazIdCaRNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbgdc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwg8RNazIdzaKIdbg8UNazIdaMgIaIMMa8RNazIdlaKIdlg8SNazIdCa8RNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfhAa5clfh8JdnaDTmbaoaLfgLIdwa8RNaLIdza8UNaLIdaMgIaIMMa8RNaLIdla8SNaLIdCa8RNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKaqadaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaoaifgLIdwaRNaLIdza8NNaLIdaMgIaIMMaRNaLIdla8PNaLIdCaRNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMh8Rava8AaD2cdtfhKaqa8LaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNa8RMMh8RaKclfhKazczfhzaLcufgLmbka8Xa8R:lMh8Xa8Yay:lMh8Yka8JaEa8Aa8Ya8X9FgzEBdba5a8EaYazEBdbaAa8Ya8XazEUdbaecefgeaH9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzaHhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbawaLcdtfazBdbaKcxfhKaHazcefgz9hmbkagak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydlh6cbhicbh8Jdnina8Mawa8Jcdtfydbcx2fgAIdwgya8W9Emeaia9e9pmeJFFuuhIdna9iaH9pmba8Mawa9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaia9h0mdkdnaSaXaAydlg9kcdtg0fydbg5fg9mRbbaSaXaAydbgYcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fg8Acwfhda8AclfhCa8Ka9ocx2fg8Lcwfhra8Lclfh9qcbhKcehednindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbg8R:tgIa9qIdbaLIdlgR:tg8NNa8LIdba8R:tg8PaEIdlaR:tgyN:taIaCIdbaR:tg8UNa8AIdba8R:tg8SayN:tNayarIdbaLIdwgR:tg8VNa8NaEIdwaR:tg8RN:tayadIdbaR:tgRNa8Ua8RN:tNa8Ra8PNa8VaIN:ta8Ra8SNaRaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6hea8EaK9hmbkkaeceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaoaLfgzaoaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2hea9ca52h8AaqhKaDhEinaKa8AfgzaKaefgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkkaAcwfhKdndndndna3aYfgLRbbc9:fPdebdkaYhzinaOazcdtgzfa5BdbaQazfydbgzaY9hmbxikkaQa0fydbhzaQa9nfydbhYaOa9nfa9kBdbazh9kkaOaYcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaifhika8Jcefg8JaH9hmbkkdnaTmbaghdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8EclfaLBdba8Ecwfa5BdbadcifhdkazcxfhzaEcifgEag6mbkadak9nmdxbkkasabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd9Ogzcdtascwffc98fhXdninazTmeaXydbcbyd:m:jjjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; + var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;T9Vsdbk;v6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascxfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgHBdxasceBd2asaHBdlascuadcitadcFFFFe0Ecbyd;O1jjbHjjjjbbgOBdzascdBd2asaOBdwasclfaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd;O1jjbHjjjjbbgXBdCasciBd2asaCcbyd;O1jjbHjjjjbbgQBdKasclBd2alcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd;O1jjbHjjjjbbgLBd3ascvBd2aLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd;S1jjbH:bjjjbbasclBd2asalcbyd;O1jjbHjjjjbbg3Bd3ascvBd2asaCcbyd;O1jjbHjjjjbbgzBdaascoBd2asaCcbyd;O1jjbHjjjjbbgKBd8KascrBd2azcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkascualcx2alc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbg8KBdycwhAascwBd2a8Kaialavz:djjjbcbhvdnaDTmbcbh8EascuaDal2gzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgvBd8ScDhAascDBd2alTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascxfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd;O1jjbHjjjjbbgKBdbasaAcefg5Bd2aKcbazz:ljjjbh8FdndndnaDTmbascxfa5cdtfaLcbyd;O1jjbHjjjjbbgqBdbasaAcdVgKBd2aqcbazz:ljjjb8AascxfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd;O1jjbHjjjjbbgwBdbasaAcifBd2awcbaKz:ljjjb8AadmexdkcbhqcbhwadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Jaeh8Ainaea8Jcdtfh8EcbhKina3a8EaKcj1jjbfydbcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:q1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekdna8KaLcx2fgYIdwa8Ka5cx2fgAIdwg8P:tgIaINaYIdbaAIdbg8U:tgyayNaYIdlaAIdlg8S:tg8Ra8RNMM:rg8NJbbbb9ETmbaIa8N:vhIa8Ra8N:vh8Raya8N:vhykJbbacJbbacJbbjZazceSEaEceSEh8Xdna8Ka8EaKc:e1jjbfydbcdtfydbcx2fgzIdwa8P:tgRaIaRaINazIdba8U:tg8YayNa8RazIdla8S:tg8WNMMg8VN:tgRaRNa8Yaya8VN:tgIaINa8Wa8Ra8VN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNg8RaINNg8VazIdbMUdbazaya8RayNg8XNg8YazIdlMUdlazaRa8RaRNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIa8RaRa8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Jcifg8Jad6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tgRaRNaKIdlaLIdlg80:tg8Ra8RNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNaRazIdba8Z:tg8PNa8RazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNa8RaIN:ta8VNh83a8Ya8RNa8SaIN:ta8VNhUa8Xa8PNaRaIN:ta8VNh85a8YaRNa8PaIN:ta8VNh86aRa8SNa8Pa8RN:tgIaINa8Ra8NNa8SayN:tgIaINaya8PNa8NaRN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tg8RNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUa8RNa83a8PNMgRNUdbazaIa86a8RNa85a8PNMg8RNUdbazcxfaIa87ayNa88aRNa8Na89a8RNMMMg8NNUdbaIayaRNNa8YMh8YaIaya8RNNa8WMh8WaIaRa8RNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIaRa8NNNa8VMh8VaIa8Ra8NNNa8XMh8XaIayayNNa80Mh80aIaRaRNNa8:Mh8:aIa8Ra8RNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaqaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyawaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydlhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbh8Mascxfasyd2gzcdtfa8MBdbasazcefgKBd2ascxfaKcdtfcuamcdtamcFFFFi0Ecbyd;O1jjbHjjjjbbgeBdbasazcdfgKBd2ascxfaKcdtfaCcbyd;O1jjbHjjjjbbgOBdbasazcifgKBd2ascxfaKcdtfalcbyd;O1jjbHjjjjbbgcBdbasazclfBd2Jbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasclfabadgoalaXz:cjjjbabhAcbhdcbhginabagcdtfh8JcbhzindnaXaAazfydbgLcdtgYfydbg5aXa8Jazc:S1jjbfydbcdtfydbgKcdtfydbgESmba3aKfRbbg8Acv2a3aLfRbbg8Efc;a1jjbfRbbgia8Ecv2a8Afg8Lc;a1jjbfRbbgHVcFeGTmbdnaEa59nmba8Lc:q1jjbfRbbcFeGmekdna8Ea8A9hmba8EcufcFeGce0mbaaaYfydbaK9hmeka8Madcx2fg5aKaLaHcFeGgEEBdla5aLaKaEEBdba5aEaiGcb9hBdwadcefhdkazclfgzcx9hmbkdnagcifggao9pmbaAcxfhAadcifam9nmekkdnadmbaohdxikcbh8AinJbbbbJbbjZa8FaXa8Ma8Acx2fg5ydlgEa5ydbg8Ea5ydwgKEgAcdtfydbgic8S2gHfgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEgYcx2fgKIdwg8RNazIdzaKIdbg8NNazIdaMgIaIMMa8RNazIdlaKIdlg8PNazIdCa8RNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbggc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwgRNazIdzaKIdbg8UNazIdaMgIaIMMaRNazIdlaKIdlg8SNazIdCaRNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfh8Ja5clfh8LdnaDTmbaqaLfgLIdwaRNaLIdza8UNaLIdaMgIaIMMaRNaLIdla8SNaLIdCaRNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKawagaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaqaHfgLIdwa8RNaLIdza8NNaLIdaMgIaIMMa8RNaLIdla8PNaLIdCa8RNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMhRavaYaD2cdtfhKawaiaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNaRMMhRaKclfhKazczfhzaLcufgLmbka8XaR:lMh8Xa8Yay:lMh8Yka8LaEaYa8Ya8X9FgzEBdba5a8EaAazEBdba8Ja8Ya8XazEUdba8Acefg8Aad9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzadhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbaeaLcdtfazBdbaKcxfhKadazcefgz9hmbkaoak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydwh6cbhHcbh8Ldnina8Maea8Lcdtfydbcx2fg8JIdwgya8W9EmeaHa9e9pmeJFFuuhIdna9iad9pmba8Maea9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaHa9h0mdkdnaSaXa8Jydlg9kcdtg0fydbg5fg9mRbbaSaXa8JydbgAcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fgYcwfhgaYclfhCa8Ka9ocx2fgicwfhraiclfh9qcbhKceh8AdnindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbgR:tgIa9qIdbaLIdlg8R:tg8NNaiIdbaR:tg8PaEIdla8R:tgyN:taIaCIdba8R:tg8UNaYIdbaR:tg8SayN:tNayarIdbaLIdwg8R:tg8VNa8NaEIdwa8R:tgRN:tayagIdba8R:tg8RNa8UaRN:tNaRa8PNa8VaIN:taRa8SNa8RaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6h8Aa8EaK9hmbkka8AceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaqaLfgzaqaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2h8Aa9ca52hYawhKaDhEinaKaYfgzaKa8AfgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkka8JcwfhKdndndndna3aAfgLRbbc9:fPdebdkaAhzinaOazcdtgzfa5BdbaQazfydbgzaA9hmbxikkaQa0fydbhzaQa9nfydbhAaOa9nfa9kBdbazh9kkaOaAcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaHfhHka8Lcefg8Lad9hmbkkdnaTmbaohdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8Ecwfa5Bdba8EclfaLBdbadcifhdkazcxfhzaEcifgEao6mbkadak9nmdxbkkasclfabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd2gzcdtascxffc98fhXdninazTmeaXydbcbyd;S1jjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk:2ldouv998Jjjjjbca9RglcFFF;7rBd3al9cFFF;7;3FF:;Fb83dCalcFFF97Bdzal9cFFF;7FFF:;u83dwdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZJbbbbalIdwalIdCgk:tgqaqJbbbb9DEgqalIdxalIdKgx:tgmamaq9DEgqalIdzalId3gm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;0Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbgqBdxawceBd2aqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd;O1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;O1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;O1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;O1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;O1jjbHjjjjbbgeBdaawcoBd2awaicbyd;O1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;S1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index 645878f925..a4ff5f1fe8 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -1,9 +1,9 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptSimplifier = (function() { - // Built with clang version 16.0.0 + // Built with clang version 18.1.2 // Built from meshoptimizer 0.20 - var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuec:G;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;H9Usdbk;N6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascwfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd1:jjjbHjjjjbbgHBdwasceBd9OasaHBdbascuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbgOBdxascdBd9OasaOBdlasaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd1:jjjbHjjjjbbgXBdzasciBd9OasaCcbyd1:jjjbHjjjjbbgQBdCasclBd9Oalcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd1:jjjbHjjjjbbgLBdKascvBd9OaLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd:m:jjjbH:bjjjbbasclBd9Oasalcbyd1:jjjbHjjjjbbg3BdKascvBd9OasaCcbyd1:jjjbHjjjjbbgzBd3ascoBd9OasaCcbyd1:jjjbHjjjjbbgKBdaascrBd9OazcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Kascwfasyd9Ogzcdtfa8KBdbasazcefgABd9Oa8Kaialavz:djjjbdndnaDmbcbhvxekcbh8EascwfaAcdtfcuaDal2gKcdtaKcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdbasazcdfgABd9OalTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascwfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd1:jjjbHjjjjbbgKBdbasaAcefg5Bd9OaKcbazz:ljjjbh8FdndndnaDTmbascwfa5cdtfaLcbyd1:jjjbHjjjjbbgoBdbasaAcdfgKBd9Oaocbazz:ljjjb8AascwfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd1:jjjbHjjjjbbgqBdbasaAcifBd9OaqcbaKz:ljjjb8AadmexdkcbhocbhqadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Eaeh8AincbhKina3aeaKc:G1jjbfydba8EfcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:W1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekJbbacJbbjZazceSEh8RaEceShAa8KaeaKc:K1jjbfydba8Efcdtfydbcx2fhzdna8KaLcx2fgEIdwa8Ka5cx2fgYIdwg8P:tgIaINaEIdbaYIdbg8U:tgyayNaEIdlaYIdlg8S:tgRaRNMM:rg8NJbbbb9ETmbaIa8N:vhIaRa8N:vhRaya8N:vhykJbbaca8RaAEh8XdnazIdwa8P:tg8RaIa8RaINazIdba8U:tg8YayNaRazIdla8S:tg8WNMMg8VN:tg8Ra8RNa8Yaya8VN:tgIaINa8WaRa8VN:tgyayNMM:rgRJbbbb9ETmba8RaR:vh8RayaR:vhyaIaR:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNgRaINNg8VazIdbMUdbazayaRayNg8XNg8YazIdlMUdlaza8RaRa8RNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIaRa8Ra8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3aza8Ra8NNg8RazIdaMUdaaza8Na8PNg8NazId8KMUd8KazaRazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3aza8RazIdaMUdaaza8NazId8KMUd8KazaRazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Ecifg8Ead6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tg8Ra8RNaKIdlaLIdlg80:tgRaRNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNa8RazIdba8Z:tg8PNaRazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNaRaIN:ta8VNh83a8YaRNa8SaIN:ta8VNhUa8Xa8PNa8RaIN:ta8VNh85a8Ya8RNa8PaIN:ta8VNh86a8Ra8SNa8PaRN:tgIaINaRa8NNa8SayN:tgIaINaya8PNa8Na8RN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tgRNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUaRNa83a8PNMg8RNUdbazaIa86aRNa85a8PNMgRNUdbazcxfaIa87ayNa88a8RNa8Na89aRNMMMg8NNUdbaIaya8RNNa8YMh8YaIayaRNNa8WMh8WaIa8RaRNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIa8Ra8NNNa8VMh8VaIaRa8NNNa8XMh8XaIayayNNa80Mh80aIa8Ra8RNNa8:Mh8:aIaRaRNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaoaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaoaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkaqaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydbhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh8Mascwfasyd9Ogzcdtfa8MBdbasazcefgKBd9OascwfaKcdtfcuamcdtamcFFFFi0Ecbyd1:jjjbHjjjjbbgwBdbasazcdfgKBd9OascwfaKcdtfaCcbyd1:jjjbHjjjjbbgOBdbasazcifgKBd9OascwfaKcdtfalcbyd1:jjjbHjjjjbbgcBdbasazclfBd9OJbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasabadggalaXz:cjjjbabhAcbhHcbhYincbhzindnaXaAazfydbgLcdtg8AfydbgEaXabazc;m1jjbfydbaYfcdtfydbgKcdtfydbg8ESmba3aKfRbbgecv2a3aLfRbbg5fc;G1jjbfRbbg8La5cv2aefg8Jc;G1jjbfRbbgiVcFeGTmbdna8Jc:W1jjbfRbbTmba8EaE0mekdna5ae9hmba5cufcFeGce0mbaaa8AfydbaK9hmeka8MaHcx2fg5aKaLaicFeGgEEBdla5aLaKaEEBdba5aEa8LGcb9hBdwaHcefhHkazclfgzcx9hmbkdnaYcifgYag9pmbaAcxfhAaHcifam9nmekkdnaHmbaghdxikcbheinJbbbbJbbjZa8FaXa8Maecx2fg5ydlgEa5ydbg8Ea5ydwgKEgYcdtfydbg8Lc8S2gifgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEg8Acx2fgKIdwgRNazIdzaKIdbg8NNazIdaMgIaIMMaRNazIdlaKIdlg8PNazIdCaRNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbgdc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwg8RNazIdzaKIdbg8UNazIdaMgIaIMMa8RNazIdlaKIdlg8SNazIdCa8RNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfhAa5clfh8JdnaDTmbaoaLfgLIdwa8RNaLIdza8UNaLIdaMgIaIMMa8RNaLIdla8SNaLIdCa8RNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKaqadaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaoaifgLIdwaRNaLIdza8NNaLIdaMgIaIMMaRNaLIdla8PNaLIdCaRNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMh8Rava8AaD2cdtfhKaqa8LaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNa8RMMh8RaKclfhKazczfhzaLcufgLmbka8Xa8R:lMh8Xa8Yay:lMh8Yka8JaEa8Aa8Ya8X9FgzEBdba5a8EaYazEBdbaAa8Ya8XazEUdbaecefgeaH9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzaHhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbawaLcdtfazBdbaKcxfhKaHazcefgz9hmbkagak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydlh6cbhicbh8Jdnina8Mawa8Jcdtfydbcx2fgAIdwgya8W9Emeaia9e9pmeJFFuuhIdna9iaH9pmba8Mawa9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaia9h0mdkdnaSaXaAydlg9kcdtg0fydbg5fg9mRbbaSaXaAydbgYcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fg8Acwfhda8AclfhCa8Ka9ocx2fg8Lcwfhra8Lclfh9qcbhKcehednindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbg8R:tgIa9qIdbaLIdlgR:tg8NNa8LIdba8R:tg8PaEIdlaR:tgyN:taIaCIdbaR:tg8UNa8AIdba8R:tg8SayN:tNayarIdbaLIdwgR:tg8VNa8NaEIdwaR:tg8RN:tayadIdbaR:tgRNa8Ua8RN:tNa8Ra8PNa8VaIN:ta8Ra8SNaRaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6hea8EaK9hmbkkaeceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaoaLfgzaoaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2hea9ca52h8AaqhKaDhEinaKa8AfgzaKaefgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkkaAcwfhKdndndndna3aYfgLRbbc9:fPdebdkaYhzinaOazcdtgzfa5BdbaQazfydbgzaY9hmbxikkaQa0fydbhzaQa9nfydbhYaOa9nfa9kBdbazh9kkaOaYcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaifhika8Jcefg8JaH9hmbkkdnaTmbaghdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8EclfaLBdba8Ecwfa5BdbadcifhdkazcxfhzaEcifgEag6mbkadak9nmdxbkkasabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd9Ogzcdtascwffc98fhXdninazTmeaXydbcbyd:m:jjjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;:ieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbarcearce0EhdinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfheadcufgdmbkkabydbcbBdbk:Zldouv998Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalczfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalczfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZalIdbalIdzgk:tJbbbb:xgqalIdlalIdCgx:tgmamaq9DEgqalIdwalIdKgm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;lOowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcwfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdwawceBd9Oaqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdxawcdBd9Oadcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd1:jjjbHjjjjbbgsBdzawciBd9Odndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdCawclBd9OdndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBdKawcvBd9Oaecbaiz:ljjjbhOavcd4hxdnadTmbaxcdth3a5hmalhAaqheadhEinaOamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaAc;81jjbalEgCIdbaiIdxMUdxaiaCIdlaiIdzMUdzaiaCIdwaiIdCMUdCaiaiIdKJbbjZMUdKamclfhmaAa3fhAaecxfheaEcufgEmbkkdnaDTmbaOcxfhiaDheinaictfgmamIdbJbbbbJbbjZaicxfIdbgH:vaHJbbbb9BEgHNUdbaic94fgmaHamIdbNUdbaic98fgmaHamIdbNUdbaiaHaiIdbNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBd3awcoBd9Oawaicbyd1:jjjbHjjjjbbgEBdaaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;81jjbalEgmIdwaOa5ydbgCc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aCcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcwffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Qdidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgoaDIdbgrarao9EEUdbaladfgDaoaDIdbgrarao9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkavJbbbb:xgvaoaoav9DEgoararao9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:jjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:jjjbfgdBd:q:jjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:G9Kbb"; + var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;T9Vsdbk;v6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascxfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgHBdxasceBd2asaHBdlascuadcitadcFFFFe0Ecbyd;O1jjbHjjjjbbgOBdzascdBd2asaOBdwasclfaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd;O1jjbHjjjjbbgXBdCasciBd2asaCcbyd;O1jjbHjjjjbbgQBdKasclBd2alcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd;O1jjbHjjjjbbgLBd3ascvBd2aLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd;S1jjbH:bjjjbbasclBd2asalcbyd;O1jjbHjjjjbbg3Bd3ascvBd2asaCcbyd;O1jjbHjjjjbbgzBdaascoBd2asaCcbyd;O1jjbHjjjjbbgKBd8KascrBd2azcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkascualcx2alc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbg8KBdycwhAascwBd2a8Kaialavz:djjjbcbhvdnaDTmbcbh8EascuaDal2gzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgvBd8ScDhAascDBd2alTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascxfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd;O1jjbHjjjjbbgKBdbasaAcefg5Bd2aKcbazz:ljjjbh8FdndndnaDTmbascxfa5cdtfaLcbyd;O1jjbHjjjjbbgqBdbasaAcdVgKBd2aqcbazz:ljjjb8AascxfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd;O1jjbHjjjjbbgwBdbasaAcifBd2awcbaKz:ljjjb8AadmexdkcbhqcbhwadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Jaeh8Ainaea8Jcdtfh8EcbhKina3a8EaKcj1jjbfydbcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:q1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekdna8KaLcx2fgYIdwa8Ka5cx2fgAIdwg8P:tgIaINaYIdbaAIdbg8U:tgyayNaYIdlaAIdlg8S:tg8Ra8RNMM:rg8NJbbbb9ETmbaIa8N:vhIa8Ra8N:vh8Raya8N:vhykJbbacJbbacJbbjZazceSEaEceSEh8Xdna8Ka8EaKc:e1jjbfydbcdtfydbcx2fgzIdwa8P:tgRaIaRaINazIdba8U:tg8YayNa8RazIdla8S:tg8WNMMg8VN:tgRaRNa8Yaya8VN:tgIaINa8Wa8Ra8VN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNg8RaINNg8VazIdbMUdbazaya8RayNg8XNg8YazIdlMUdlazaRa8RaRNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIa8RaRa8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Jcifg8Jad6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tgRaRNaKIdlaLIdlg80:tg8Ra8RNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNaRazIdba8Z:tg8PNa8RazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNa8RaIN:ta8VNh83a8Ya8RNa8SaIN:ta8VNhUa8Xa8PNaRaIN:ta8VNh85a8YaRNa8PaIN:ta8VNh86aRa8SNa8Pa8RN:tgIaINa8Ra8NNa8SayN:tgIaINaya8PNa8NaRN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tg8RNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUa8RNa83a8PNMgRNUdbazaIa86a8RNa85a8PNMg8RNUdbazcxfaIa87ayNa88aRNa8Na89a8RNMMMg8NNUdbaIayaRNNa8YMh8YaIaya8RNNa8WMh8WaIaRa8RNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIaRa8NNNa8VMh8VaIa8Ra8NNNa8XMh8XaIayayNNa80Mh80aIaRaRNNa8:Mh8:aIa8Ra8RNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaqaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyawaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydlhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbh8Mascxfasyd2gzcdtfa8MBdbasazcefgKBd2ascxfaKcdtfcuamcdtamcFFFFi0Ecbyd;O1jjbHjjjjbbgeBdbasazcdfgKBd2ascxfaKcdtfaCcbyd;O1jjbHjjjjbbgOBdbasazcifgKBd2ascxfaKcdtfalcbyd;O1jjbHjjjjbbgcBdbasazclfBd2Jbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasclfabadgoalaXz:cjjjbabhAcbhdcbhginabagcdtfh8JcbhzindnaXaAazfydbgLcdtgYfydbg5aXa8Jazc:S1jjbfydbcdtfydbgKcdtfydbgESmba3aKfRbbg8Acv2a3aLfRbbg8Efc;a1jjbfRbbgia8Ecv2a8Afg8Lc;a1jjbfRbbgHVcFeGTmbdnaEa59nmba8Lc:q1jjbfRbbcFeGmekdna8Ea8A9hmba8EcufcFeGce0mbaaaYfydbaK9hmeka8Madcx2fg5aKaLaHcFeGgEEBdla5aLaKaEEBdba5aEaiGcb9hBdwadcefhdkazclfgzcx9hmbkdnagcifggao9pmbaAcxfhAadcifam9nmekkdnadmbaohdxikcbh8AinJbbbbJbbjZa8FaXa8Ma8Acx2fg5ydlgEa5ydbg8Ea5ydwgKEgAcdtfydbgic8S2gHfgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEgYcx2fgKIdwg8RNazIdzaKIdbg8NNazIdaMgIaIMMa8RNazIdlaKIdlg8PNazIdCa8RNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbggc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwgRNazIdzaKIdbg8UNazIdaMgIaIMMaRNazIdlaKIdlg8SNazIdCaRNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfh8Ja5clfh8LdnaDTmbaqaLfgLIdwaRNaLIdza8UNaLIdaMgIaIMMaRNaLIdla8SNaLIdCaRNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKawagaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaqaHfgLIdwa8RNaLIdza8NNaLIdaMgIaIMMa8RNaLIdla8PNaLIdCa8RNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMhRavaYaD2cdtfhKawaiaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNaRMMhRaKclfhKazczfhzaLcufgLmbka8XaR:lMh8Xa8Yay:lMh8Yka8LaEaYa8Ya8X9FgzEBdba5a8EaAazEBdba8Ja8Ya8XazEUdba8Acefg8Aad9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzadhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbaeaLcdtfazBdbaKcxfhKadazcefgz9hmbkaoak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydwh6cbhHcbh8Ldnina8Maea8Lcdtfydbcx2fg8JIdwgya8W9EmeaHa9e9pmeJFFuuhIdna9iad9pmba8Maea9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaHa9h0mdkdnaSaXa8Jydlg9kcdtg0fydbg5fg9mRbbaSaXa8JydbgAcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fgYcwfhgaYclfhCa8Ka9ocx2fgicwfhraiclfh9qcbhKceh8AdnindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbgR:tgIa9qIdbaLIdlg8R:tg8NNaiIdbaR:tg8PaEIdla8R:tgyN:taIaCIdba8R:tg8UNaYIdbaR:tg8SayN:tNayarIdbaLIdwg8R:tg8VNa8NaEIdwa8R:tgRN:tayagIdba8R:tg8RNa8UaRN:tNaRa8PNa8VaIN:taRa8SNa8RaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6h8Aa8EaK9hmbkka8AceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaqaLfgzaqaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2h8Aa9ca52hYawhKaDhEinaKaYfgzaKa8AfgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkka8JcwfhKdndndndna3aAfgLRbbc9:fPdebdkaAhzinaOazcdtgzfa5BdbaQazfydbgzaA9hmbxikkaQa0fydbhzaQa9nfydbhAaOa9nfa9kBdbazh9kkaOaAcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaHfhHka8Lcefg8Lad9hmbkkdnaTmbaohdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8Ecwfa5Bdba8EclfaLBdbadcifhdkazcxfhzaEcifgEao6mbkadak9nmdxbkkasclfabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd2gzcdtascxffc98fhXdninazTmeaXydbcbyd;S1jjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk:2ldouv998Jjjjjbca9RglcFFF;7rBd3al9cFFF;7;3FF:;Fb83dCalcFFF97Bdzal9cFFF;7FFF:;u83dwdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZJbbbbalIdwalIdCgk:tgqaqJbbbb9DEgqalIdxalIdKgx:tgmamaq9DEgqalIdzalId3gm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;0Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbgqBdxawceBd2aqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd;O1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;O1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;O1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;O1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;O1jjbHjjjjbbgeBdaawcoBd2awaicbyd;O1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;S1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); From 95de74ad7fe605f8ba1ef9c0c3728b55179844d7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 24 May 2024 16:56:05 -0700 Subject: [PATCH 081/581] Update WASI SDK for GHA CI to 22 (clang 18) --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27b8cc19d2..6f2af0b63f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,7 +106,7 @@ jobs: curl -sL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$VERSION/wasi-sysroot-$VERSION.0.tar.gz | tar xz -C wasi-sdk-$VERSION.0/share mv wasi-sdk-$VERSION.0 wasi-sdk env: - VERSION: 20 + VERSION: 22 - name: build run: | make -j2 -B WASI_SDK=wasi-sdk gltf/library.wasm js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fff7e67944..0622f571e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: curl -sL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$VERSION/wasi-sysroot-$VERSION.0.tar.gz | tar xz -C wasi-sdk-$VERSION.0/share mv wasi-sdk-$VERSION.0 wasi-sdk env: - VERSION: 20 + VERSION: 22 - name: build run: | make -j2 -B WASI_SDK=wasi-sdk gltf/library.wasm js From bafbb0c10087e78e1be94314d59037946f612fdc Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 25 May 2024 14:49:38 -0700 Subject: [PATCH 082/581] extern: Improve EXT_mesh_gpu_instancing validation in cgltf With this change we validate that instanced meshes have a mesh, have attributes and that all attributes agree on the number of elements. This makes sure that using the instancing data is less error prone and is unlikely to lead to memory safety issues. The same change was submitted upstream: https://github.com/jkuhlmann/cgltf/pull/252 --- extern/cgltf.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/extern/cgltf.h b/extern/cgltf.h index 17dc0ca5d2..ac392aba43 100644 --- a/extern/cgltf.h +++ b/extern/cgltf.h @@ -1697,7 +1697,20 @@ cgltf_result cgltf_validate(cgltf_data* data) { if (data->nodes[i].weights && data->nodes[i].mesh) { - CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf); + } + + if (data->nodes[i].has_mesh_gpu_instancing) + { + CGLTF_ASSERT_IF(data->nodes[i].mesh == NULL, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes_count == 0, cgltf_result_invalid_gltf); + + cgltf_accessor* first = data->nodes[i].mesh_gpu_instancing.attributes[0].data; + + for (cgltf_size k = 0; k < data->nodes[i].mesh_gpu_instancing.attributes_count; ++k) + { + CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes[k].data->count != first->count, cgltf_result_invalid_gltf); + } } } From f7ec441e85f2f4cf11fad823cacd4c97d3e280c1 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 26 May 2024 15:02:26 -0700 Subject: [PATCH 083/581] gltfpack: Relax node/instance processing rules Previously, we had an invariant where a mesh had either nodes but no instances, instances but no nodes, or nothing (in which case it was treated as root-attached). We now relax the processing to allow meshes to have both nodes and instances. When instances are specified, we still rely on mesh.scene, so instances are implicitly scoped to a single scene root (and also can't be animated via their node ancestors). --- gltf/gltfpack.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 2db6eff776..dee7a930a1 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -281,7 +281,10 @@ static void process(cgltf_data* data, const char* input_path, const char* output for (size_t i = 0; i < meshes.size(); ++i) { Mesh& mesh = meshes[i]; - assert(mesh.instances.empty()); + + // mesh is already instanced, skip + if (!mesh.instances.empty()) + continue; // mesh is already world space, skip if (mesh.nodes.empty()) @@ -664,9 +667,6 @@ static void process(cgltf_data* data, const char* input_path, const char* output append(json_meshes, "}"); - assert(mesh.nodes.empty() || mesh.instances.empty()); - ext_instancing = ext_instancing || !mesh.instances.empty(); - if (mesh.nodes.size()) { for (size_t j = 0; j < mesh.nodes.size(); ++j) @@ -691,7 +691,8 @@ static void process(cgltf_data* data, const char* input_path, const char* output } } } - else if (mesh.instances.size()) + + if (mesh.instances.size()) { assert(mesh.scene >= 0); comma(json_roots[mesh.scene]); @@ -704,7 +705,8 @@ static void process(cgltf_data* data, const char* input_path, const char* output node_offset++; } - else + + if (mesh.nodes.empty() && mesh.instances.empty()) { assert(mesh.scene >= 0); comma(json_roots[mesh.scene]); @@ -716,6 +718,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output } mesh_offset++; + ext_instancing = ext_instancing || !mesh.instances.empty(); // skip all meshes that we've written in this iteration assert(pi > i); From 64614f1478c99526e78f7a94ae673354d26fb1eb Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 26 May 2024 15:04:06 -0700 Subject: [PATCH 084/581] gltfpack: Parse EXT_mesh_gpu_instancing extension into mesh instances When -mi is not specified but the input scene has instancing extension, we convert the instances to the internal world-space transform representation, which can then be serialized using our existing code. Note that instances are not attached to nodes in the internal representation; animation and scene data is thus silently discarded for now. This is not ideal but is not trivial to change as it would require reworking other parts of the processing pipeline. --- gltf/parsegltf.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 91f0c020fd..90694d987f 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -275,6 +275,61 @@ static void parseMeshesGltf(cgltf_data* data, std::vector& meshes, std::ve } } +static void parseMeshInstancesGltf(cgltf_data* data, std::vector& instances, cgltf_node* node) +{ + cgltf_accessor* translation = NULL; + cgltf_accessor* rotation = NULL; + cgltf_accessor* scale = NULL; + + for (size_t i = 0; i < node->mesh_gpu_instancing.attributes_count; ++i) + { + cgltf_attribute& attr = node->mesh_gpu_instancing.attributes[i]; + + if (strcmp(attr.name, "TRANSLATION") == 0 && attr.data->type == cgltf_type_vec3) + translation = attr.data; + else if (strcmp(attr.name, "ROTATION") == 0 && attr.data->type == cgltf_type_vec4) + rotation = attr.data; + else if (strcmp(attr.name, "SCALE") == 0 && attr.data->type == cgltf_type_vec3) + scale = attr.data; + } + + size_t count = translation ? translation->count : (rotation ? rotation->count : (scale ? scale->count : 0)); + + // todo move to cgltf? + if (count == 0 || (translation && translation->count != count) || (rotation && rotation->count != count) || (scale && scale->count != count)) + { + fprintf(stderr, "Warning: ignoring instancing data in node %d as no transforms are present\n", int(node - data->nodes)); + return; + } + + instances.reserve(instances.size() + count); + + cgltf_node instance = {}; + instance.parent = node; + instance.has_translation = translation != NULL; + instance.has_rotation = rotation != NULL; + instance.has_scale = scale != NULL; + instance.rotation[3] = 1.f; + instance.scale[0] = 1.f; + instance.scale[1] = 1.f; + instance.scale[2] = 1.f; + + for (size_t i = 0; i < count; ++i) + { + if (translation) + cgltf_accessor_read_float(translation, i, instance.translation, sizeof(float)); + if (rotation) + cgltf_accessor_read_float(rotation, i, instance.rotation, sizeof(float)); + if (scale) + cgltf_accessor_read_float(scale, i, instance.scale, sizeof(float)); + + Transform xf; + cgltf_node_transform_world(&instance, xf.data); + + instances.push_back(xf); + } +} + static void parseMeshNodesGltf(cgltf_data* data, std::vector& meshes, const std::vector >& mesh_remap) { for (size_t i = 0; i < data->nodes_count; ++i) @@ -289,7 +344,7 @@ static void parseMeshNodesGltf(cgltf_data* data, std::vector& meshes, cons { Mesh* mesh = &meshes[mi]; - if (!mesh->nodes.empty() && mesh->skin != node.skin) + if (mesh->skin != node.skin && (!mesh->nodes.empty() || !mesh->instances.empty())) { // this should be extremely rare - if the same mesh is used with different skins, we need to duplicate it // in this case we don't spend any effort on keeping the number of duplicates to the minimum, because this @@ -298,8 +353,15 @@ static void parseMeshNodesGltf(cgltf_data* data, std::vector& meshes, cons mesh = &meshes.back(); } - mesh->nodes.push_back(&node); mesh->skin = node.skin; + + if (node.has_mesh_gpu_instancing) + { + mesh->scene = 0; // TODO + parseMeshInstancesGltf(data, mesh->instances, &node); + } + else + mesh->nodes.push_back(&node); } } @@ -308,7 +370,7 @@ static void parseMeshNodesGltf(cgltf_data* data, std::vector& meshes, cons Mesh& mesh = meshes[i]; // because the rest of gltfpack assumes that empty nodes array = world-space mesh, we need to filter unused meshes - if (mesh.nodes.empty()) + if (mesh.nodes.empty() && mesh.instances.empty()) { mesh.streams.clear(); mesh.indices.clear(); @@ -530,8 +592,6 @@ static cgltf_data* parseGltf(cgltf_data* data, cgltf_result result, std::vector< *error = getError(result, data); else if (requiresExtension(data, "KHR_draco_mesh_compression")) *error = "file requires Draco mesh compression support"; - else if (requiresExtension(data, "EXT_mesh_gpu_instancing")) - *error = "file requires mesh instancing support"; else if (needsDummyBuffers(data)) *error = "buffer has no data"; From f4f453c71f1526ac64a4cafa93cb8ded15e4aa96 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 26 May 2024 15:09:08 -0700 Subject: [PATCH 085/581] gltfpack: Simplify instance count calculation Since cgltf guarantees that all attributes will have the same count, we can simply use the first accessor. --- gltf/parsegltf.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 90694d987f..99f9c22afd 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -275,7 +275,7 @@ static void parseMeshesGltf(cgltf_data* data, std::vector& meshes, std::ve } } -static void parseMeshInstancesGltf(cgltf_data* data, std::vector& instances, cgltf_node* node) +static void parseMeshInstancesGltf(std::vector& instances, cgltf_node* node) { cgltf_accessor* translation = NULL; cgltf_accessor* rotation = NULL; @@ -293,14 +293,7 @@ static void parseMeshInstancesGltf(cgltf_data* data, std::vector& ins scale = attr.data; } - size_t count = translation ? translation->count : (rotation ? rotation->count : (scale ? scale->count : 0)); - - // todo move to cgltf? - if (count == 0 || (translation && translation->count != count) || (rotation && rotation->count != count) || (scale && scale->count != count)) - { - fprintf(stderr, "Warning: ignoring instancing data in node %d as no transforms are present\n", int(node - data->nodes)); - return; - } + size_t count = node->mesh_gpu_instancing.attributes[0].data->count; instances.reserve(instances.size() + count); @@ -358,7 +351,7 @@ static void parseMeshNodesGltf(cgltf_data* data, std::vector& meshes, cons if (node.has_mesh_gpu_instancing) { mesh->scene = 0; // TODO - parseMeshInstancesGltf(data, mesh->instances, &node); + parseMeshInstancesGltf(mesh->instances, &node); } else mesh->nodes.push_back(&node); From bc4ab587e5ad37033ce1c43f6223573f81b2f6dc Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 26 May 2024 15:14:39 -0700 Subject: [PATCH 086/581] gltf: Update README.md Add EXT_mesh_gpu_instancing support for input files. --- gltf/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/gltf/README.md b/gltf/README.md index a6be164051..ffe6d1e12f 100644 --- a/gltf/README.md +++ b/gltf/README.md @@ -83,6 +83,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th - KHR_mesh_quantization - KHR_texture_basisu - KHR_texture_transform +- EXT_mesh_gpu_instancing - EXT_meshopt_compression Even if the source file does not use extensions, gltfpack may use some extensions in the output file either by default or when certain options are used: From 3c08b842b5763759e4d1762318ed47c456c6e43c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 27 May 2024 00:53:01 -0700 Subject: [PATCH 087/581] gltfpack: Preserve mesh attributes if the texture exists with no image There are some cases when the texture refers to a NULL image, eg when an unknown image extension is used such as EXT_texture_webp. In this case we used to remove UV coordinates which triggered excessive validation errors; we now preserve UV coordinates even though the texture object is not fully serialized/processed. --- gltf/material.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gltf/material.cpp b/gltf/material.cpp index 8d017a1871..a6e861f7d9 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -457,14 +457,17 @@ static void analyzeMaterialTexture(const cgltf_texture_view& view, TextureKind k mi.usesTextureTransform |= hasValidTransform(view); if (view.texture) + { textures[view.texture - data->textures].keep = true; + mi.textureSetMask |= 1u << view.texcoord; + mi.needsTangents |= (kind == TextureKind_Normal); + } + if (const cgltf_image* image = getTextureImage(view.texture)) { ImageInfo& info = images[image - data->images]; - mi.textureSetMask |= 1u << view.texcoord; - mi.needsTangents |= (kind == TextureKind_Normal); if (info.kind == TextureKind_Generic) info.kind = kind; From 52e7e9e9043ab9c81cd118bf190cfd1aa6d5d5ff Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 27 May 2024 09:24:31 -0700 Subject: [PATCH 088/581] Update glTF-Sample-Assets paths We should be able to work with the KTX files that are part of the repository, but DiffuseTransmissionPlant is still broken due to the use of webp mime type so it will need to be disabled for now. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6f2af0b63f..16c42a30f8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -84,7 +84,7 @@ jobs: - name: test run: find glTF-Sample-Assets -name *.gltf -or -name *.glb | xargs -d '\n' ./gltfpack -cc -test - name: pack - run: find glTF-Sample-Assets -name *.gltf | grep -v 'glTF-Draco\|glTF-KTX' | xargs -d '\n' -I '{}' ./gltfpack -i '{}' -o '{}pack.gltf' + run: find glTF-Sample-Assets -name *.gltf | grep -v 'glTF-Draco\|DiffuseTransmissionPlant' | xargs -d '\n' -I '{}' ./gltfpack -i '{}' -o '{}pack.gltf' - name: validate run: | curl -sL $VALIDATOR | tar xJ From 4b63c99f62dcf6d187e90b8b9629a479dc2a02d3 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 27 May 2024 09:41:01 -0700 Subject: [PATCH 089/581] gltfpack: Slightly refactor instance processing There's no need to assign skin for instanced meshes as it must be NULL. --- gltf/parsegltf.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 99f9c22afd..783dd245d7 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -346,15 +346,16 @@ static void parseMeshNodesGltf(cgltf_data* data, std::vector& meshes, cons mesh = &meshes.back(); } - mesh->skin = node.skin; - if (node.has_mesh_gpu_instancing) { - mesh->scene = 0; // TODO + mesh->scene = 0; // TODO: we need to assign scene index since instances are attached to a scene; for now we assume 0 parseMeshInstancesGltf(mesh->instances, &node); } else + { + mesh->skin = node.skin; mesh->nodes.push_back(&node); + } } } From 2f820c23dd68cab53ddd16d6d7e6d099bf72a454 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 27 May 2024 09:44:11 -0700 Subject: [PATCH 090/581] gltfpack: Warn when EXT_mesh_gpu_instancing is used with multiple scenes Since we attach instances to scene 0, this only works when there's only one scene. Note that fully correct processing would need to implement multi-scene instancing in data structures, as a mesh doesn't always have a consistent scene index. --- gltf/parsegltf.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index 783dd245d7..f83356b70e 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -348,7 +348,7 @@ static void parseMeshNodesGltf(cgltf_data* data, std::vector& meshes, cons if (node.has_mesh_gpu_instancing) { - mesh->scene = 0; // TODO: we need to assign scene index since instances are attached to a scene; for now we assume 0 + mesh->scene = 0; // we need to assign scene index since instances are attached to a scene; for now we assume 0 parseMeshInstancesGltf(mesh->instances, &node); } else @@ -597,6 +597,8 @@ static cgltf_data* parseGltf(cgltf_data* data, cgltf_result result, std::vector< if (requiresExtension(data, "KHR_mesh_quantization")) fprintf(stderr, "Warning: file uses quantized geometry; repacking may result in increased quantization error\n"); + if (requiresExtension(data, "EXT_mesh_gpu_instancing") && data->scenes_count > 1) + fprintf(stderr, "Warning: file uses instancing and has more than one scene; results may be incorrect\n"); std::vector > mesh_remap; From 69294a6651e6254a86db45b0d8126198fe5ca501 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 29 May 2024 17:04:12 -0700 Subject: [PATCH 091/581] gltfpack: Unify QuantizationPosition node_scale computation Instead of recomputing node_scale in every place where QuantizationPosition is used, compute it once and store it in the struct. This ensures that all computations are using the same value. --- gltf/gltfpack.h | 2 ++ gltf/stream.cpp | 2 ++ gltf/write.cpp | 27 +++++++++------------------ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index 0af349536a..cdcbdc64eb 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -170,6 +170,8 @@ struct QuantizationPosition float scale; int bits; bool normalized; + + float node_scale; // computed from scale/bits/normalized }; struct QuantizationTexture diff --git a/gltf/stream.cpp b/gltf/stream.cpp index b5bc1955e0..57a175b190 100644 --- a/gltf/stream.cpp +++ b/gltf/stream.cpp @@ -97,6 +97,8 @@ QuantizationPosition prepareQuantizationPosition(const std::vector& meshes result.scale = std::max(b.max.f[0] - b.min.f[0], std::max(b.max.f[1] - b.min.f[1], b.max.f[2] - b.min.f[2])); } + result.node_scale = result.scale / float((1 << result.bits) - 1) * (result.normalized ? 65535.f : 1.f); + return result; } diff --git a/gltf/write.cpp b/gltf/write.cpp index abcae6d42c..9b1fc4c321 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -471,11 +471,9 @@ static void writeMaterialComponent(std::string& json, const cgltf_data* data, co if (tm.thickness_factor != 0) { // thickness is in mesh coordinate space which is rescaled by quantization - float node_scale = qp ? qp->scale / float((1 << qp->bits) - 1) * (qp->normalized ? 65535.f : 1.f) : 1.f; - comma(json); append(json, "\"thicknessFactor\":"); - append(json, tm.thickness_factor / node_scale); + append(json, tm.thickness_factor / (qp ? qp->node_scale : 1.f)); } if (memcmp(tm.attenuation_color, white, 12) != 0) { @@ -1097,8 +1095,6 @@ size_t writeJointBindMatrices(std::vector& views, std::string& json_ if (settings.quantize && !settings.pos_float) { - float node_scale = qp.scale / float((1 << qp.bits) - 1) * (qp.normalized ? 65535.f : 1.f); - // pos_offset has to be applied first, thus it results in an offset rotated by the bind matrix transform[12] += qp.offset[0] * transform[0] + qp.offset[1] * transform[4] + qp.offset[2] * transform[8]; transform[13] += qp.offset[0] * transform[1] + qp.offset[1] * transform[5] + qp.offset[2] * transform[9]; @@ -1106,7 +1102,7 @@ size_t writeJointBindMatrices(std::vector& views, std::string& json_ // node_scale will be applied before the rotation/scale from transform for (int k = 0; k < 12; ++k) - transform[k] *= node_scale; + transform[k] *= qp.node_scale; } scratch.append(reinterpret_cast(transform), sizeof(transform)); @@ -1156,17 +1152,15 @@ size_t writeInstances(std::vector& views, std::string& json_accessor { const float* transform = transforms[i].data; - float node_scale = qp.scale / float((1 << qp.bits) - 1) * (qp.normalized ? 65535.f : 1.f); - // pos_offset has to be applied first, thus it results in an offset rotated by the instance matrix position[i].f[0] += qp.offset[0] * transform[0] + qp.offset[1] * transform[4] + qp.offset[2] * transform[8]; position[i].f[1] += qp.offset[0] * transform[1] + qp.offset[1] * transform[5] + qp.offset[2] * transform[9]; position[i].f[2] += qp.offset[0] * transform[2] + qp.offset[1] * transform[6] + qp.offset[2] * transform[10]; // node_scale will be applied before the rotation/scale from transform - scale[i].f[0] *= node_scale; - scale[i].f[1] *= node_scale; - scale[i].f[2] *= node_scale; + scale[i].f[0] *= qp.node_scale; + scale[i].f[1] *= qp.node_scale; + scale[i].f[2] *= qp.node_scale; } } @@ -1186,14 +1180,11 @@ void writeMeshNode(std::string& json, size_t mesh_offset, cgltf_node* node, cglt append(json, mesh_offset); if (skin) { - comma(json); - append(json, "\"skin\":"); + append(json, ",\"skin\":"); append(json, size_t(skin - data->skins)); } if (qp) { - float node_scale = qp->scale / float((1 << qp->bits) - 1) * (qp->normalized ? 65535.f : 1.f); - append(json, ",\"translation\":["); append(json, qp->offset[0]); append(json, ","); @@ -1201,11 +1192,11 @@ void writeMeshNode(std::string& json, size_t mesh_offset, cgltf_node* node, cglt append(json, ","); append(json, qp->offset[2]); append(json, "],\"scale\":["); - append(json, node_scale); + append(json, qp->node_scale); append(json, ","); - append(json, node_scale); + append(json, qp->node_scale); append(json, ","); - append(json, node_scale); + append(json, qp->node_scale); append(json, "]"); } if (node && node->weights_count) From 6616d595411c65b998ceb9f3e4a06ab8a8df6266 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 29 May 2024 17:08:46 -0700 Subject: [PATCH 092/581] gltfpack: Attach meshes directly to nodes when quantization is a no-op If the input model is already quantized with the same settings wrt position encoding, then the computed quantization parameters result in a no-op transform (offset 0, scale 1). However, repeat invocations of gltfpack will each add one extra node with a no-op transform. With this change, if we can afford to attach the mesh directly we will do so. Note that in the future, we could also merge node transforms via the hierarchy, but that should be a separate optional optimization as it can interfere with application processing logic. --- gltf/gltfpack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index dee7a930a1..5205a584fc 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -675,7 +675,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output assert(ni.keep); // if we don't use position quantization, prefer attaching the mesh to its node directly - if (!ni.has_mesh && (!settings.quantize || settings.pos_float)) + if (!ni.has_mesh && (!settings.quantize || settings.pos_float || (qp.offset[0] == 0.f && qp.offset[1] == 0.f && qp.offset[2] == 0 && qp.node_scale == 1.f))) { ni.has_mesh = true; ni.mesh_index = mesh_offset; From 62532239a205440245be15e06d4c0720f965cdd4 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 30 May 2024 09:02:41 -0700 Subject: [PATCH 093/581] Update bug_report.md I'm really not sure how to change the wording at this point but maybe this will help. --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ab8ecead55..6949faaec8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Create a report if you believe you've found a bug in this project; please use GitHub Discussions instead if you think the bug may be in your code. +about: Create a report if you've found a bug in this project; please use GitHub Discussions instead if you are uncertain or the bug may be in your code. title: '' labels: bug assignees: '' From c0e7ed0215ed24d0a0742014c91c98a5fa94639c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 30 May 2024 09:03:01 -0700 Subject: [PATCH 094/581] Update feature_request.md Add a missing dot. --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 910caa9d10..1dbda009db 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,6 +1,6 @@ --- name: Feature request -about: Suggest a feature for this project; please use GitHub Discussions if your idea is not sufficiently concrete +about: Suggest a feature for this project; please use GitHub Discussions if your idea is not sufficiently concrete. title: '' labels: enhancement assignees: '' From c9fd0916d56d86fe8bec2803d7b8b0ddcff6ad1a Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 3 Jun 2024 15:01:23 -0700 Subject: [PATCH 095/581] Update GHA CI to remove DiffuseTransmissionPlant exclusion We no longer need this since the asset was fixed to use PNG. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16c42a30f8..1f23671fbc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -84,7 +84,7 @@ jobs: - name: test run: find glTF-Sample-Assets -name *.gltf -or -name *.glb | xargs -d '\n' ./gltfpack -cc -test - name: pack - run: find glTF-Sample-Assets -name *.gltf | grep -v 'glTF-Draco\|DiffuseTransmissionPlant' | xargs -d '\n' -I '{}' ./gltfpack -i '{}' -o '{}pack.gltf' + run: find glTF-Sample-Assets -name *.gltf | grep -v 'glTF-Draco' | xargs -d '\n' -I '{}' ./gltfpack -i '{}' -o '{}pack.gltf' - name: validate run: | curl -sL $VALIDATOR | tar xJ From 8d8d60ed91a65aaefdf9160065505c56155efca8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 4 Jun 2024 16:26:48 -0700 Subject: [PATCH 096/581] extern: Update to fast_obj 1.3 fast_obj 1.3 makes a change to internal data structures to use indexed texture objects; in this change we blindly rework the code to index the new textures[] array; this will be reworked in a subsequent change to directly use the underlying indexing to do obj->gltf mapping. --- extern/fast_obj.h | 113 +++++++++++++++++++++++++++------------------- gltf/parseobj.cpp | 14 +++--- 2 files changed, 74 insertions(+), 53 deletions(-) diff --git a/extern/fast_obj.h b/extern/fast_obj.h index c57522b314..41cce80f74 100644 --- a/extern/fast_obj.h +++ b/extern/fast_obj.h @@ -1,7 +1,7 @@ /* * fast_obj * - * Version 1.2 + * Version 1.3 * * MIT License * @@ -31,7 +31,7 @@ #define FAST_OBJ_HDR #define FAST_OBJ_VERSION_MAJOR 1 -#define FAST_OBJ_VERSION_MINOR 2 +#define FAST_OBJ_VERSION_MINOR 3 #define FAST_OBJ_VERSION ((FAST_OBJ_VERSION_MAJOR << 8) | FAST_OBJ_VERSION_MINOR) #include @@ -68,16 +68,16 @@ typedef struct /* Set for materials that don't come from the associated mtllib */ int fallback; - /* Texture maps */ - fastObjTexture map_Ka; - fastObjTexture map_Kd; - fastObjTexture map_Ks; - fastObjTexture map_Ke; - fastObjTexture map_Kt; - fastObjTexture map_Ns; - fastObjTexture map_Ni; - fastObjTexture map_d; - fastObjTexture map_bump; + /* Texture map indices in fastObjMesh textures array */ + unsigned int map_Ka; + unsigned int map_Kd; + unsigned int map_Ks; + unsigned int map_Ke; + unsigned int map_Kt; + unsigned int map_Ns; + unsigned int map_Ni; + unsigned int map_d; + unsigned int map_bump; } fastObjMaterial; @@ -114,6 +114,10 @@ typedef struct } fastObjGroup; +/* Note: a dummy zero-initialized value is added to the first index + of the positions, texcoords, normals and textures arrays. Hence, + valid indices into these arrays start from 1, with an index of 0 + indicating that the attribute is not present. */ typedef struct { /* Vertex data */ @@ -142,6 +146,10 @@ typedef struct unsigned int material_count; fastObjMaterial* materials; + /* Texture maps */ + unsigned int texture_count; + fastObjTexture* textures; + /* Mesh objects ('o' tag in .obj file) */ unsigned int object_count; fastObjGroup* objects; @@ -326,7 +334,7 @@ unsigned long file_size(void* file, void* user_data) long p; long n; (void)(user_data); - + f = (FILE*)(file); p = ftell(f); @@ -760,8 +768,10 @@ const char* parse_face(fastObjData* data, const char* ptr) if (v < 0) vn.p = (array_size(data->mesh->positions) / 3) - (fastObjUInt)(-v); - else + else if (v > 0) vn.p = (fastObjUInt)(v); + else + return ptr; /* Skip lines with no valid vertex index */ if (t < 0) vn.t = (array_size(data->mesh->texcoords) / 2) - (fastObjUInt)(-t); @@ -877,15 +887,15 @@ fastObjMaterial mtl_default(void) mtl.fallback = 0; - mtl.map_Ka = map_default(); - mtl.map_Kd = map_default(); - mtl.map_Ks = map_default(); - mtl.map_Ke = map_default(); - mtl.map_Kt = map_default(); - mtl.map_Ns = map_default(); - mtl.map_Ni = map_default(); - mtl.map_d = map_default(); - mtl.map_bump = map_default(); + mtl.map_Ka = 0; + mtl.map_Kd = 0; + mtl.map_Ks = 0; + mtl.map_Ke = 0; + mtl.map_Kt = 0; + mtl.map_Ns = 0; + mtl.map_Ni = 0; + mtl.map_d = 0; + mtl.map_bump = 0; return mtl; } @@ -918,8 +928,8 @@ const char* parse_usemtl(fastObjData* data, const char* ptr) idx++; } - /* If doesn't exists, create a default one with this name - Note: this case happens when OBJ doesn't have its MTL */ + /* If doesn't exist, create a default one with this name + Note: this case happens when OBJ doesn't have its MTL */ if (idx == array_size(data->mesh->materials)) { fastObjMaterial new_mtl = mtl_default(); @@ -945,16 +955,6 @@ void map_clean(fastObjTexture* map) static void mtl_clean(fastObjMaterial* mtl) { - map_clean(&mtl->map_Ka); - map_clean(&mtl->map_Kd); - map_clean(&mtl->map_Ks); - map_clean(&mtl->map_Ke); - map_clean(&mtl->map_Kt); - map_clean(&mtl->map_Ns); - map_clean(&mtl->map_Ni); - map_clean(&mtl->map_d); - map_clean(&mtl->map_bump); - memory_dealloc(mtl->name); } @@ -985,12 +985,12 @@ const char* read_mtl_triple(const char* p, float v[3]) static -const char* read_map(fastObjData* data, const char* ptr, fastObjTexture* map) +const char* read_map(fastObjData* data, const char* ptr, unsigned int* idx) { - const char* s; - const char* e; - char* name; - char* path; + const char* s; + const char* e; + fastObjTexture* map; + ptr = skip_whitespace(ptr); @@ -1004,13 +1004,26 @@ const char* read_map(fastObjData* data, const char* ptr, fastObjTexture* map) ptr = skip_name(ptr); e = ptr; - name = string_copy(s, e); + /* Try to find an existing texture map with the same name */ + *idx = 1; /* skip dummy at index 0 */ + while (*idx < array_size(data->mesh->textures)) + { + map = &data->mesh->textures[*idx]; + if (map->name && string_equal(map->name, s, e)) + break; - path = string_concat(data->base, s, e); - string_fix_separators(path); + (*idx)++; + } - map->name = name; - map->path = path; + /* Add it to the texture array if it didn't already exist */ + if (*idx == array_size(data->mesh->textures)) + { + fastObjTexture new_map = map_default(); + new_map.name = string_copy(s, e); + new_map.path = string_concat(data->base, s, e); + string_fix_separators(new_map.path); + array_push(data->mesh->textures, new_map); + } return e; } @@ -1376,6 +1389,9 @@ void fast_obj_destroy(fastObjMesh* m) for (ii = 0; ii < array_size(m->materials); ii++) mtl_clean(&m->materials[ii]); + for (ii = 0; ii < array_size(m->textures); ii++) + map_clean(&m->textures[ii]); + array_clean(m->positions); array_clean(m->texcoords); array_clean(m->normals); @@ -1386,6 +1402,7 @@ void fast_obj_destroy(fastObjMesh* m) array_clean(m->objects); array_clean(m->groups); array_clean(m->materials); + array_clean(m->textures); memory_dealloc(m); } @@ -1439,11 +1456,12 @@ fastObjMesh* fast_obj_read_with_callbacks(const char* path, const fastObjCallbac m->face_materials = 0; m->indices = 0; m->materials = 0; + m->textures = 0; m->objects = 0; m->groups = 0; - /* Add dummy position/texcoord/normal */ + /* Add dummy position/texcoord/normal/texture */ array_push(m->positions, 0.0f); array_push(m->positions, 0.0f); array_push(m->positions, 0.0f); @@ -1455,6 +1473,8 @@ fastObjMesh* fast_obj_read_with_callbacks(const char* path, const fastObjCallbac array_push(m->normals, 0.0f); array_push(m->normals, 1.0f); + array_push(m->textures, map_default()); + /* Data needed during parsing */ data.mesh = m; @@ -1546,6 +1566,7 @@ fastObjMesh* fast_obj_read_with_callbacks(const char* path, const fastObjCallbac m->face_count = array_size(m->face_vertices); m->index_count = array_size(m->indices); m->material_count = array_size(m->materials); + m->texture_count = array_size(m->textures); m->object_count = array_size(m->objects); m->group_count = array_size(m->groups); diff --git a/gltf/parseobj.cpp b/gltf/parseobj.cpp index 7ed713c077..8de9159896 100644 --- a/gltf/parseobj.cpp +++ b/gltf/parseobj.cpp @@ -37,8 +37,8 @@ static void parseMaterialsObj(fastObjMesh* obj, cgltf_data* data) { fastObjMaterial& om = obj->materials[mi]; - if (om.map_Kd.name && textureIndex(textures, om.map_Kd.name) < 0) - textures.push_back(om.map_Kd.name); + if (obj->textures[om.map_Kd].name && textureIndex(textures, obj->textures[om.map_Kd].name) < 0) + textures.push_back(obj->textures[om.map_Kd].name); } data->images = (cgltf_image*)calloc(textures.size(), sizeof(cgltf_image)); @@ -81,9 +81,9 @@ static void parseMaterialsObj(fastObjMesh* obj, cgltf_data* data) gm.alpha_cutoff = 0.5f; - if (om.map_Kd.name) + if (obj->textures[om.map_Kd].name) { - gm.pbr_metallic_roughness.base_color_texture.texture = &data->textures[textureIndex(textures, om.map_Kd.name)]; + gm.pbr_metallic_roughness.base_color_texture.texture = &data->textures[textureIndex(textures, obj->textures[om.map_Kd].name)]; gm.pbr_metallic_roughness.base_color_texture.scale = 1.0f; gm.alpha_mode = (om.illum == 4 || om.illum == 6 || om.illum == 7 || om.illum == 9) ? cgltf_alpha_mode_mask : cgltf_alpha_mode_opaque; @@ -95,10 +95,10 @@ static void parseMaterialsObj(fastObjMesh* obj, cgltf_data* data) gm.pbr_metallic_roughness.base_color_factor[2] = om.Kd[2]; } - if (om.map_d.name) + if (obj->textures[om.map_d].name) { - if (om.map_Kd.name && strcmp(om.map_Kd.name, om.map_d.name) != 0) - fprintf(stderr, "Warning: material has different diffuse and alpha textures (Kd: %s, d: %s) and might not render correctly\n", om.map_Kd.name, om.map_d.name); + if (obj->textures[om.map_Kd].name && strcmp(obj->textures[om.map_Kd].name, obj->textures[om.map_d].name) != 0) + fprintf(stderr, "Warning: material has different diffuse and alpha textures (Kd: %s, d: %s) and might not render correctly\n", obj->textures[om.map_Kd].name, obj->textures[om.map_d].name); gm.alpha_mode = cgltf_alpha_mode_blend; } From d5af1432acc525c4fa2de0908360e299564763ce Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 4 Jun 2024 22:11:41 -0700 Subject: [PATCH 097/581] gltfpack: Simplify texture matching code for .obj We still can't quite use .obj texture indices directly because we might end up with a set of unused textures that later parts of pipeline don't filter out, but we can remove all string operations and just compare indices instead. --- gltf/parseobj.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/gltf/parseobj.cpp b/gltf/parseobj.cpp index 8de9159896..a1813366e8 100644 --- a/gltf/parseobj.cpp +++ b/gltf/parseobj.cpp @@ -12,7 +12,7 @@ static void defaultFree(void*, void* p) free(p); } -static int textureIndex(const std::vector& textures, const char* name) +static int textureIndex(const std::vector& textures, unsigned int name) { for (size_t i = 0; i < textures.size(); ++i) if (textures[i] == name) @@ -31,14 +31,16 @@ static void fixupUri(char* uri) static void parseMaterialsObj(fastObjMesh* obj, cgltf_data* data) { - std::vector textures; + // every texture in obj has a unique id (1+); we convert it to a 0-based index + // this effectively extracts only used textures out of the obj, as we don't remove unused textures later in the processing + std::vector textures; for (unsigned int mi = 0; mi < obj->material_count; ++mi) { fastObjMaterial& om = obj->materials[mi]; - if (obj->textures[om.map_Kd].name && textureIndex(textures, obj->textures[om.map_Kd].name) < 0) - textures.push_back(obj->textures[om.map_Kd].name); + if (om.map_Kd && textureIndex(textures, om.map_Kd) < 0) + textures.push_back(om.map_Kd); } data->images = (cgltf_image*)calloc(textures.size(), sizeof(cgltf_image)); @@ -46,7 +48,8 @@ static void parseMaterialsObj(fastObjMesh* obj, cgltf_data* data) for (size_t i = 0; i < textures.size(); ++i) { - data->images[i].uri = strdup(textures[i].c_str()); + unsigned int id = textures[i]; + data->images[i].uri = strdup(obj->textures[id].name); fixupUri(data->images[i].uri); } @@ -81,9 +84,9 @@ static void parseMaterialsObj(fastObjMesh* obj, cgltf_data* data) gm.alpha_cutoff = 0.5f; - if (obj->textures[om.map_Kd].name) + if (om.map_Kd) { - gm.pbr_metallic_roughness.base_color_texture.texture = &data->textures[textureIndex(textures, obj->textures[om.map_Kd].name)]; + gm.pbr_metallic_roughness.base_color_texture.texture = &data->textures[textureIndex(textures, om.map_Kd)]; gm.pbr_metallic_roughness.base_color_texture.scale = 1.0f; gm.alpha_mode = (om.illum == 4 || om.illum == 6 || om.illum == 7 || om.illum == 9) ? cgltf_alpha_mode_mask : cgltf_alpha_mode_opaque; @@ -95,9 +98,9 @@ static void parseMaterialsObj(fastObjMesh* obj, cgltf_data* data) gm.pbr_metallic_roughness.base_color_factor[2] = om.Kd[2]; } - if (obj->textures[om.map_d].name) + if (om.map_d) { - if (obj->textures[om.map_Kd].name && strcmp(obj->textures[om.map_Kd].name, obj->textures[om.map_d].name) != 0) + if (om.map_Kd && strcmp(obj->textures[om.map_Kd].name, obj->textures[om.map_d].name) != 0) fprintf(stderr, "Warning: material has different diffuse and alpha textures (Kd: %s, d: %s) and might not render correctly\n", obj->textures[om.map_Kd].name, obj->textures[om.map_d].name); gm.alpha_mode = cgltf_alpha_mode_blend; From 0d23cb0c289f569205dd0dd7723cf34b7d0669c4 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 6 Jun 2024 11:46:27 -0700 Subject: [PATCH 098/581] gltfpack: Fix code style in MaterialInfo Not sure why this used the wrong field naming convention. Also do a minor rename in NodeInfo. --- gltf/gltfpack.cpp | 8 +++----- gltf/gltfpack.h | 8 ++++---- gltf/material.cpp | 7 +++---- gltf/mesh.cpp | 4 ++-- gltf/node.cpp | 4 ++-- gltf/write.cpp | 2 +- 6 files changed, 15 insertions(+), 18 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 5205a584fc..4266642f07 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -364,8 +364,8 @@ static void process(cgltf_data* data, const char* input_path, const char* output { MaterialInfo vi = materials[mesh.variants[j].material - data->materials]; - mi.needsTangents |= vi.needsTangents; - mi.textureSetMask |= vi.textureSetMask; + mi.needs_tangents |= vi.needs_tangents; + mi.texture_set_mask |= vi.texture_set_mask; mi.unlit &= vi.unlit; } @@ -547,7 +547,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output ext_anisotropy = ext_anisotropy || material.has_anisotropy; ext_dispersion = ext_dispersion || material.has_dispersion; ext_unlit = ext_unlit || material.unlit; - ext_texture_transform = ext_texture_transform || mi.usesTextureTransform; + ext_texture_transform = ext_texture_transform || mi.uses_texture_transform; } for (size_t i = 0; i < meshes.size(); ++i) @@ -848,9 +848,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output const char* ext = data->extensions_required[i]; if (!isExtensionSupported(extensions, sizeof(extensions) / sizeof(extensions[0]), ext)) - { fprintf(stderr, "Warning: required extension %s is not supported and will be skipped\n", ext); - } } writeExtensions(json, extensions, sizeof(extensions) / sizeof(extensions[0])); diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index cdcbdc64eb..743a1b4079 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -206,7 +206,7 @@ struct NodeInfo bool keep; bool animated; - unsigned int animated_paths; + unsigned int animated_path_mask; int remap; @@ -221,11 +221,11 @@ struct MaterialInfo { bool keep; - bool usesTextureTransform; - bool needsTangents; + bool uses_texture_transform; + bool needs_tangents; bool unlit; - unsigned int textureSetMask; + unsigned int texture_set_mask; int remap; }; diff --git a/gltf/material.cpp b/gltf/material.cpp index a6e861f7d9..0931b2e05b 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -454,21 +454,20 @@ static const cgltf_image* getTextureImage(const cgltf_texture* texture) static void analyzeMaterialTexture(const cgltf_texture_view& view, TextureKind kind, MaterialInfo& mi, cgltf_data* data, std::vector& textures, std::vector& images) { - mi.usesTextureTransform |= hasValidTransform(view); + mi.uses_texture_transform |= hasValidTransform(view); if (view.texture) { textures[view.texture - data->textures].keep = true; - mi.textureSetMask |= 1u << view.texcoord; - mi.needsTangents |= (kind == TextureKind_Normal); + mi.texture_set_mask |= 1u << view.texcoord; + mi.needs_tangents |= (kind == TextureKind_Normal); } if (const cgltf_image* image = getTextureImage(view.texture)) { ImageInfo& info = images[image - data->images]; - if (info.kind == TextureKind_Generic) info.kind = kind; else if (info.kind > kind) // this is useful to keep color textures that have attrib data in alpha tagged as color diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index 3f35ce7ba9..e1f3d1a623 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -409,7 +409,7 @@ void filterStreams(Mesh& mesh, const MaterialInfo& mi) morph_tangent = morph_tangent || (stream.type == cgltf_attribute_type_tangent && !isConstant(stream.data, {0, 0, 0, 0})); } - if (stream.type == cgltf_attribute_type_texcoord && stream.index < 32 && (mi.textureSetMask & (1u << stream.index)) != 0) + if (stream.type == cgltf_attribute_type_texcoord && stream.index < 32 && (mi.texture_set_mask & (1u << stream.index)) != 0) { keep_texture_set = std::max(keep_texture_set, stream.index); } @@ -427,7 +427,7 @@ void filterStreams(Mesh& mesh, const MaterialInfo& mi) if (stream.type == cgltf_attribute_type_normal && mi.unlit) continue; - if (stream.type == cgltf_attribute_type_tangent && !mi.needsTangents) + if (stream.type == cgltf_attribute_type_tangent && !mi.needs_tangents) continue; if ((stream.type == cgltf_attribute_type_joints || stream.type == cgltf_attribute_type_weights) && !mesh.skin) diff --git a/gltf/node.cpp b/gltf/node.cpp index bfe37274b5..c3da288457 100644 --- a/gltf/node.cpp +++ b/gltf/node.cpp @@ -45,7 +45,7 @@ void markAnimated(cgltf_data* data, std::vector& nodes, const std::vec { NodeInfo& ni = nodes[track.node - data->nodes]; - ni.animated_paths |= (1 << track.path); + ni.animated_path_mask |= (1 << track.path); } } } @@ -55,7 +55,7 @@ void markAnimated(cgltf_data* data, std::vector& nodes, const std::vec NodeInfo& ni = nodes[i]; for (cgltf_node* node = &data->nodes[i]; node; node = node->parent) - ni.animated |= nodes[node - data->nodes].animated_paths != 0; + ni.animated |= nodes[node - data->nodes].animated_path_mask != 0; } } diff --git a/gltf/write.cpp b/gltf/write.cpp index 9b1fc4c321..be6a492fff 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -1395,7 +1395,7 @@ void writeAnimation(std::string& json, std::vector& views, std::stri if (!ni.keep) continue; - if (!settings.anim_const && (ni.animated_paths & (1 << track.path)) == 0) + if (!settings.anim_const && (ni.animated_path_mask & (1 << track.path)) == 0) continue; tracks.push_back(&track); From db416fba9ffc4cf201d1f79c1426532ba24c2a7d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 10 Jun 2024 14:46:48 -0700 Subject: [PATCH 099/581] demo: Switch processDev to run simplify There's no significant work planned on meshlets at this time but there's some outstanding work on simplify/simplifyAttr. --- demo/main.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index aeb8256994..017b2e0051 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -1245,11 +1245,7 @@ void processDev(const char* path) if (!loadMesh(mesh, path)) return; - Mesh copy = mesh; - meshopt_optimizeVertexCache(©.indices[0], ©.indices[0], copy.indices.size(), copy.vertices.size()); - meshopt_optimizeVertexFetch(©.vertices[0], ©.indices[0], copy.indices.size(), ©.vertices[0], copy.vertices.size(), sizeof(Vertex)); - - meshlets(copy, false); + simplify(mesh); } int main(int argc, char** argv) From d643b0b44f9ac16f8177e0f01fa65955e486010e Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 12 Jun 2024 12:08:10 -0700 Subject: [PATCH 100/581] demo: Rework .obj reindexing to use fastObjIndex data Instead of building a full unindexed vertex buffer, we now build a remap table using .obj index structure, and fill vertex/index buffers using this remap. This approach is already being used by gltfpack so this brings the two versions in line; it's also often faster. Maybe most importantly though, this opens up an opportunity to use position indices when .obj file has no normals/texture coordinates, which would align vertex indices with .obj file and help debug various algorithms with Blender's help as it also keeps internal indices aligned with .obj. For now this change doesn't do it and simply generates a fresh remap. --- demo/main.cpp | 84 +++++++++++++++++++++++++------------------------- demo/tests.cpp | 7 ++--- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index 017b2e0051..f3ac62d76f 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -76,66 +76,66 @@ Mesh parseObj(const char* path, double& reindex) return Mesh(); } + reindex = timestamp(); + size_t total_indices = 0; for (unsigned int i = 0; i < obj->face_count; ++i) total_indices += 3 * (obj->face_vertices[i] - 2); - std::vector vertices(total_indices); + size_t face_vertex_count = obj->index_count; + + std::vector remap(face_vertex_count); + size_t unique_vertices = meshopt_generateVertexRemap(&remap[0], NULL, face_vertex_count, obj->indices, face_vertex_count, sizeof(fastObjIndex)); + + Mesh mesh; + mesh.vertices.resize(unique_vertices); + mesh.indices.resize(total_indices); + + for (unsigned int vi = 0; vi < face_vertex_count; ++vi) + { + unsigned int target = remap[vi]; + // TODO: this fills every target vertex multiple times + + fastObjIndex ii = obj->indices[vi]; + + Vertex v = { + obj->positions[ii.p * 3 + 0], + obj->positions[ii.p * 3 + 1], + obj->positions[ii.p * 3 + 2], + obj->normals[ii.n * 3 + 0], + obj->normals[ii.n * 3 + 1], + obj->normals[ii.n * 3 + 2], + obj->texcoords[ii.t * 2 + 0], + obj->texcoords[ii.t * 2 + 1], + }; + + mesh.vertices[target] = v; + } size_t vertex_offset = 0; size_t index_offset = 0; - for (unsigned int i = 0; i < obj->face_count; ++i) + for (unsigned int fi = 0; fi < obj->face_count; ++fi) { - for (unsigned int j = 0; j < obj->face_vertices[i]; ++j) - { - fastObjIndex gi = obj->indices[index_offset + j]; + unsigned int face_vertices = obj->face_vertices[fi]; - Vertex v = - { - obj->positions[gi.p * 3 + 0], - obj->positions[gi.p * 3 + 1], - obj->positions[gi.p * 3 + 2], - obj->normals[gi.n * 3 + 0], - obj->normals[gi.n * 3 + 1], - obj->normals[gi.n * 3 + 2], - obj->texcoords[gi.t * 2 + 0], - obj->texcoords[gi.t * 2 + 1], - }; - - // triangulate polygon on the fly; offset-3 is always the first polygon vertex - if (j >= 3) - { - vertices[vertex_offset + 0] = vertices[vertex_offset - 3]; - vertices[vertex_offset + 1] = vertices[vertex_offset - 1]; - vertex_offset += 2; - } + for (unsigned int vi = 2; vi < face_vertices; ++vi) + { + size_t to = index_offset + (vi - 2) * 3; - vertices[vertex_offset] = v; - vertex_offset++; + mesh.indices[to + 0] = remap[vertex_offset]; + mesh.indices[to + 1] = remap[vertex_offset + vi - 1]; + mesh.indices[to + 2] = remap[vertex_offset + vi]; } - index_offset += obj->face_vertices[i]; + vertex_offset += face_vertices; + index_offset += (face_vertices - 2) * 3; } fast_obj_destroy(obj); - reindex = timestamp(); - - Mesh result; - - std::vector remap(total_indices); - - size_t total_vertices = meshopt_generateVertexRemap(&remap[0], NULL, total_indices, &vertices[0], total_indices, sizeof(Vertex)); - - result.indices.resize(total_indices); - meshopt_remapIndexBuffer(&result.indices[0], NULL, total_indices, &remap[0]); - - result.vertices.resize(total_vertices); - meshopt_remapVertexBuffer(&result.vertices[0], &vertices[0], total_indices, sizeof(Vertex), &remap[0]); - - return result; + return mesh; } void dumpObj(const Mesh& mesh, bool recomputeNormals = false) diff --git a/demo/tests.cpp b/demo/tests.cpp index 58ec3de18c..7c94ba935c 100644 --- a/demo/tests.cpp +++ b/demo/tests.cpp @@ -1200,9 +1200,9 @@ static void simplifyLockFlags() }; unsigned char lock[9] = { - 1, 1, 1, - 1, 0, 1, - 1, 1, 1, // clang-format :-/ + 1, 1, 1, + 1, 0, 1, + 1, 1, 1, // clang-format :-/ }; // 0 1 2 @@ -1233,7 +1233,6 @@ static void simplifyLockFlags() assert(memcmp(ib, expected, sizeof(expected)) == 0); } - static void adjacency() { // 0 1/4 From 892e53e8cd250cc6bb5362e9c5ec4810e19428b4 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 12 Jun 2024 22:24:24 -0700 Subject: [PATCH 101/581] gltfpack: Remove generation of meshlet bounds meshes The bounding spheres here hurt more than they help: due to the lack of a material by default they obscure the actual meshlets, and if the importer merges the meshes on import then these become hard to separate. Additionally, the spheres mostly don't help with debugging meshlet clustering. It could make sense to switch to a mesh per meshet for this visualization in the future if we decide having a sense of meshlet size is important, but for now the pure visualization is more helpful. --- gltf/gltfpack.cpp | 4 +-- gltf/gltfpack.h | 2 +- gltf/mesh.cpp | 63 +---------------------------------------------- 3 files changed, 3 insertions(+), 66 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 4266642f07..d42371d016 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -398,10 +398,8 @@ static void process(cgltf_data* data, const char* input_path, const char* output if (settings.meshlet_debug > 0) { Mesh meshlets = {}; - Mesh bounds = {}; - debugMeshlets(mesh, meshlets, bounds, settings.meshlet_debug, /* scan= */ false); + debugMeshlets(mesh, meshlets, settings.meshlet_debug, /* scan= */ false); debug_meshes.push_back(meshlets); - debug_meshes.push_back(bounds); } } #endif diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index 743a1b4079..9633959112 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -306,7 +306,7 @@ void processAnimation(Animation& animation, const Settings& settings); void processMesh(Mesh& mesh, const Settings& settings); void debugSimplify(const Mesh& mesh, Mesh& kinds, Mesh& loops, float ratio, bool attributes); -void debugMeshlets(const Mesh& mesh, Mesh& meshlets, Mesh& bounds, int max_vertices, bool scan); +void debugMeshlets(const Mesh& mesh, Mesh& meshlets, int max_vertices, bool scan); bool compareMeshTargets(const Mesh& lhs, const Mesh& rhs); bool compareMeshVariants(const Mesh& lhs, const Mesh& rhs); diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index e1f3d1a623..a956569ab8 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -884,7 +884,7 @@ void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio, bo } } -void debugMeshlets(const Mesh& source, Mesh& meshlets, Mesh& bounds, int max_vertices, bool scan) +void debugMeshlets(const Mesh& source, Mesh& meshlets, int max_vertices, bool scan) { Mesh mesh = source; assert(mesh.type == cgltf_primitive_type_triangles); @@ -947,66 +947,5 @@ void debugMeshlets(const Mesh& source, Mesh& meshlets, Mesh& bounds, int max_ver meshlets.type = cgltf_primitive_type_triangles; meshlets.streams.push_back(mv); meshlets.streams.push_back(mc); - - // generate bounds meshes, using a sphere per meshlet - bounds.nodes = mesh.nodes; - - Stream bv = {cgltf_attribute_type_position}; - Stream bc = {cgltf_attribute_type_color}; - - for (size_t i = 0; i < ml.size(); ++i) - { - const meshopt_Meshlet& m = ml[i]; - - meshopt_Bounds mb = meshopt_computeMeshletBounds(&mlv[m.vertex_offset], &mlt[m.triangle_offset], m.triangle_count, positions->data[0].f, positions->data.size(), sizeof(Attr)); - - unsigned int h = unsigned(i); - h ^= h >> 13; - h *= 0x5bd1e995; - h ^= h >> 15; - - Attr c = {{float(h & 0xff) / 255.f, float((h >> 8) & 0xff) / 255.f, float((h >> 16) & 0xff) / 255.f, 0.1f}}; - - unsigned int offset = unsigned(bv.data.size()); - - const int N = 10; - - for (int y = 0; y <= N; ++y) - { - float u = (y == N) ? 0 : float(y) / N * 2 * 3.1415926f; - float sinu = sinf(u), cosu = cosf(u); - - for (int x = 0; x <= N; ++x) - { - float v = float(x) / N * 3.1415926f; - float sinv = sinf(v), cosv = cosf(v); - - float fx = sinv * cosu; - float fy = sinv * sinu; - float fz = cosv; - - Attr p = {{mb.center[0] + mb.radius * fx, mb.center[1] + mb.radius * fy, mb.center[2] + mb.radius * fz, 1.f}}; - - bv.data.push_back(p); - bc.data.push_back(c); - } - } - - for (int y = 0; y < N; ++y) - for (int x = 0; x < N; ++x) - { - bounds.indices.push_back(offset + (N + 1) * (y + 0) + (x + 0)); - bounds.indices.push_back(offset + (N + 1) * (y + 0) + (x + 1)); - bounds.indices.push_back(offset + (N + 1) * (y + 1) + (x + 0)); - - bounds.indices.push_back(offset + (N + 1) * (y + 1) + (x + 0)); - bounds.indices.push_back(offset + (N + 1) * (y + 0) + (x + 1)); - bounds.indices.push_back(offset + (N + 1) * (y + 1) + (x + 1)); - } - } - - bounds.type = cgltf_primitive_type_triangles; - bounds.streams.push_back(bv); - bounds.streams.push_back(bc); } #endif From 761ae4b640dd40474d508f148a8f7b16c3995fce Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 13 Jun 2024 21:26:12 -0700 Subject: [PATCH 102/581] demo: Implement a basic example of cluster simplification This is an important building block for Nanite, as it requires a repeated application of buildMeshlets => simplify (with additional algorithms that meshoptimizer currently doesn't support, like grouping meshlets based on proximity). This can be used to refine future improvements to simplification like sparsity, as well as serve as a basic example. For simplicity we use LockBorders flag instead of locking boundary vertices manually via meshopt_simplifyWithAttributes; from production perspective both options are viable. --- demo/main.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/demo/main.cpp b/demo/main.cpp index f3ac62d76f..e3969ec983 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -641,6 +641,52 @@ void simplifyComplete(const Mesh& mesh) } } +void simplifyClusters(const Mesh& mesh, float threshold = 0.2f) +{ + // note: we use clusters that are larger than normal to give simplifier room to work; in practice you'd use cluster groups merged from smaller clusters and build a cluster DAG + const size_t max_vertices = 255; + const size_t max_triangles = 512; + + double start = timestamp(); + + size_t max_meshlets = meshopt_buildMeshletsBound(mesh.indices.size(), max_vertices, max_triangles); + std::vector meshlets(max_meshlets); + std::vector meshlet_vertices(max_meshlets * max_vertices); + std::vector meshlet_triangles(max_meshlets * max_triangles * 3); + + meshlets.resize(meshopt_buildMeshlets(&meshlets[0], &meshlet_vertices[0], &meshlet_triangles[0], &mesh.indices[0], mesh.indices.size(), &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), max_vertices, max_triangles, 0.f)); + + double middle = timestamp(); + + std::vector lod; + lod.reserve(mesh.indices.size()); + + for (size_t i = 0; i < meshlets.size(); ++i) + { + const meshopt_Meshlet& m = meshlets[i]; + + size_t cluster_offset = lod.size(); + + for (size_t j = 0; j < m.triangle_count * 3; ++j) + lod.push_back(meshlet_vertices[m.vertex_offset + meshlet_triangles[m.triangle_offset + j]]); + + unsigned int options = meshopt_SimplifyLockBorder; + + size_t cluster_target = size_t(float(m.triangle_count) * threshold) * 3; + size_t cluster_size = meshopt_simplify(&lod[cluster_offset], &lod[cluster_offset], m.triangle_count * 3, &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), cluster_target, threshold, options, 0); + + // simplified cluster is available in lod[cluster_offset..cluster_offset + cluster_size] + lod.resize(cluster_offset + cluster_size); + } + + double end = timestamp(); + + printf("%-9s: %d triangles => %d triangles in %.2f msec, clusterized in %.2f msec\n", + "SimplifyN", // N for Nanite + int(mesh.indices.size() / 3), int(lod.size() / 3), + (end - middle) * 1000, (middle - start) * 1000); +} + void optimize(const Mesh& mesh, const char* name, void (*optf)(Mesh& mesh)) { Mesh copy = mesh; @@ -1245,7 +1291,7 @@ void processDev(const char* path) if (!loadMesh(mesh, path)) return; - simplify(mesh); + simplifyClusters(mesh); } int main(int argc, char** argv) From 1af1bf87de9a2dbccd8f605fbea64f340cc03903 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 13 Jun 2024 22:21:59 -0700 Subject: [PATCH 103/581] simplify: Implement initial support for sparse simplification When simplifying a small subset of the larger mesh, all computations that go over the entire vertex buffer become expensive; this adds up even when done once, and especially when done for every pass. This change introduces a sparse simplification mode that instructs the simplifier to optimize based on the assumption that the subset of the mesh that is being simplified is small. In that case it's worth spending extra time to convert indices into a small 0..U subrange, do all internal processing assuming we are working with a small vertex/index buffer, and remap the indices at the end. While this processing could be done externally, that is less efficient as it requires constant copying of position/attribute data; in constrast, we can do it fairly cheaply. We need to take sparse_remap into account for any code that indexes input position/attribute data; buildPositionRemap needs this as well as it currently works off of original (unscaled) data. buildSparseRemap does need to perform O(dense) work if we want to avoid using hash maps for deduplication/filtering; this change uses a small zeroed array and a large sparsely-initialized array to reduce the cost. This is subject to future improvements (although is fairly performant as it is when simplifying 500-triangle subsets of a 800K triangle mesh). --- demo/main.cpp | 2 +- src/meshoptimizer.h | 2 + src/simplifier.cpp | 93 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 77 insertions(+), 20 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index e3969ec983..665951aa88 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -670,7 +670,7 @@ void simplifyClusters(const Mesh& mesh, float threshold = 0.2f) for (size_t j = 0; j < m.triangle_count * 3; ++j) lod.push_back(meshlet_vertices[m.vertex_offset + meshlet_triangles[m.triangle_offset + j]]); - unsigned int options = meshopt_SimplifyLockBorder; + unsigned int options = meshopt_SimplifyLockBorder | meshopt_SimplifySparse; size_t cluster_target = size_t(float(m.triangle_count) * threshold) * 3; size_t cluster_size = meshopt_simplify(&lod[cluster_offset], &lod[cluster_offset], m.triangle_count * 3, &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), cluster_target, threshold, options, 0); diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index c377eebbc3..a01e6cf4fd 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -330,6 +330,8 @@ enum { /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ meshopt_SimplifyLockBorder = 1 << 0, + /* Improve simplification performance assuming input indices are a sparse subset of the mesh. Note that error becomes relative to subset extents. */ + meshopt_SimplifySparse = 1 << 1, }; /** diff --git a/src/simplifier.cpp b/src/simplifier.cpp index a84b33270a..9d3d5bac59 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -111,10 +111,12 @@ struct PositionHasher { const float* vertex_positions; size_t vertex_stride_float; + const unsigned int* sparse_remap; size_t hash(unsigned int index) const { - const unsigned int* key = reinterpret_cast(vertex_positions + index * vertex_stride_float); + unsigned int ri = sparse_remap ? sparse_remap[index] : index; + const unsigned int* key = reinterpret_cast(vertex_positions + ri * vertex_stride_float); // scramble bits to make sure that integer coordinates have entropy in lower bits unsigned int x = key[0] ^ (key[0] >> 17); @@ -127,7 +129,10 @@ struct PositionHasher bool equal(unsigned int lhs, unsigned int rhs) const { - return memcmp(vertex_positions + lhs * vertex_stride_float, vertex_positions + rhs * vertex_stride_float, sizeof(float) * 3) == 0; + unsigned int li = sparse_remap ? sparse_remap[lhs] : lhs; + unsigned int ri = sparse_remap ? sparse_remap[rhs] : rhs; + + return memcmp(vertex_positions + li * vertex_stride_float, vertex_positions + ri * vertex_stride_float, sizeof(float) * 3) == 0; } }; @@ -167,9 +172,9 @@ static T* hashLookup2(T* table, size_t buckets, const Hash& hash, const T& key, return NULL; } -static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, meshopt_Allocator& allocator) +static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const unsigned int* sparse_remap, meshopt_Allocator& allocator) { - PositionHasher hasher = {vertex_positions_data, vertex_positions_stride / sizeof(float)}; + PositionHasher hasher = {vertex_positions_data, vertex_positions_stride / sizeof(float), sparse_remap}; size_t table_size = hashBuckets2(vertex_count); unsigned int* table = allocator.allocate(table_size); @@ -205,6 +210,43 @@ static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const f allocator.deallocate(table); } +static unsigned int* buildSparseRemap(unsigned int* indices, size_t index_count, size_t vertex_count, size_t* out_vertex_count, meshopt_Allocator& allocator) +{ + unsigned char* filter = allocator.allocate(vertex_count); + memset(filter, 0, vertex_count); + + size_t unique = 0; + for (size_t i = 0; i < index_count; ++i) + { + assert(indices[i] < vertex_count); + unique += filter[indices[i]] == 0; + filter[indices[i]] = 1; + } + + unsigned int* revremap = allocator.allocate(vertex_count); + + unsigned int* remap = allocator.allocate(unique); + size_t offset = 0; + for (size_t i = 0; i < index_count; ++i) + { + if (filter[indices[i]] == 1) + { + remap[offset] = indices[i]; + filter[indices[i]] = 0; + revremap[indices[i]] = unsigned(offset); + indices[i] = unsigned(offset); + offset++; + } + else + { + indices[i] = revremap[indices[i]]; + } + } + + *out_vertex_count = unique; + return remap; +} + enum VertexKind { Kind_Manifold, // not on an attribute seam, not on any boundary @@ -383,7 +425,7 @@ struct Vector3 float x, y, z; }; -static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride) +static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const unsigned int* sparse_remap = NULL) { size_t vertex_stride_float = vertex_positions_stride / sizeof(float); @@ -392,7 +434,8 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat for (size_t i = 0; i < vertex_count; ++i) { - const float* v = vertex_positions_data + i * vertex_stride_float; + unsigned int ri = sparse_remap ? sparse_remap[i] : i; + const float* v = vertex_positions_data + ri * vertex_stride_float; if (result) { @@ -431,15 +474,17 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat return extent; } -static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count) +static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* sparse_remap) { size_t vertex_attributes_stride_float = vertex_attributes_stride / sizeof(float); for (size_t i = 0; i < vertex_count; ++i) { + unsigned int ri = sparse_remap ? sparse_remap[i] : unsigned(i); + for (size_t k = 0; k < attribute_count; ++k) { - float a = vertex_attributes_data[i * vertex_attributes_stride_float + k]; + float a = vertex_attributes_data[ri * vertex_attributes_stride_float + k]; result[i * attribute_count + k] = a * attribute_weights[k]; } @@ -1481,7 +1526,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(target_index_count <= index_count); - assert((options & ~(meshopt_SimplifyLockBorder)) == 0); + assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse)) == 0); assert(vertex_attributes_stride >= attribute_count * sizeof(float) && vertex_attributes_stride <= 256); assert(vertex_attributes_stride % sizeof(float) == 0); assert(attribute_count <= kMaxAttributes); @@ -1489,16 +1534,24 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic meshopt_Allocator allocator; unsigned int* result = destination; + if (result != indices) + memcpy(result, indices, index_count * sizeof(unsigned int)); + + // build an index remap and update indices/vertex_count to minimize the subsequent work + // note: as a consequence, errors will be computed relative to the subset extent + unsigned int* sparse_remap = NULL; + if (options & meshopt_SimplifySparse) + sparse_remap = buildSparseRemap(result, index_count, vertex_count, &vertex_count, allocator); // build adjacency information EdgeAdjacency adjacency = {}; prepareEdgeAdjacency(adjacency, index_count, vertex_count, allocator); - updateEdgeAdjacency(adjacency, indices, index_count, vertex_count, NULL); + updateEdgeAdjacency(adjacency, result, index_count, vertex_count, NULL); // build position remap that maps each vertex to the one with identical position unsigned int* remap = allocator.allocate(vertex_count); unsigned int* wedge = allocator.allocate(vertex_count); - buildPositionRemap(remap, wedge, vertex_positions_data, vertex_count, vertex_positions_stride, allocator); + buildPositionRemap(remap, wedge, vertex_positions_data, vertex_count, vertex_positions_stride, sparse_remap, allocator); // classify vertices; vertex kind determines collapse rules, see kCanCollapse unsigned char* vertex_kind = allocator.allocate(vertex_count); @@ -1522,14 +1575,14 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic #endif Vector3* vertex_positions = allocator.allocate(vertex_count); - rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride); + rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride, sparse_remap); float* vertex_attributes = NULL; if (attribute_count) { vertex_attributes = allocator.allocate(vertex_count * attribute_count); - rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count); + rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count, sparse_remap); } Quadric* vertex_quadrics = allocator.allocate(vertex_count); @@ -1547,14 +1600,11 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic memset(attribute_gradients, 0, vertex_count * attribute_count * sizeof(QuadricGrad)); } - fillFaceQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap); - fillEdgeQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap, vertex_kind, loop, loopback); + fillFaceQuadrics(vertex_quadrics, result, index_count, vertex_positions, remap); + fillEdgeQuadrics(vertex_quadrics, result, index_count, vertex_positions, remap, vertex_kind, loop, loopback); if (attribute_count) - fillAttributeQuadrics(attribute_quadrics, attribute_gradients, indices, index_count, vertex_positions, vertex_attributes, attribute_count, remap); - - if (result != indices) - memcpy(result, indices, index_count * sizeof(unsigned int)); + fillAttributeQuadrics(attribute_quadrics, attribute_gradients, result, index_count, vertex_positions, vertex_attributes, attribute_count, remap); #if TRACE size_t pass_count = 0; @@ -1630,6 +1680,11 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic memcpy(meshopt_simplifyDebugLoopBack, loopback, vertex_count * sizeof(unsigned int)); #endif + // convert resulting indices back into the dense space of the larger mesh + if (sparse_remap) + for (size_t i = 0; i < result_count; ++i) + result[i] = sparse_remap[result[i]]; + // result_error is quadratic; we need to remap it back to linear if (out_result_error) *out_result_error = sqrtf(result_error); From 30a4a25d4ea96401b13a1032031324c05014fc4c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 13 Jun 2024 23:13:45 -0700 Subject: [PATCH 104/581] simplify: Deallocate reverse remap when buildSparseRemap is done This reduces the high watermark and may allow reusing the deallocated space for the actual simplifier state. Ideally we would reduce the space consumed here further, but that requires a hash map so may not be ideal. --- src/simplifier.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 9d3d5bac59..6c016f7b3d 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -223,27 +223,35 @@ static unsigned int* buildSparseRemap(unsigned int* indices, size_t index_count, filter[indices[i]] = 1; } - unsigned int* revremap = allocator.allocate(vertex_count); - unsigned int* remap = allocator.allocate(unique); size_t offset = 0; + + // temporary map dense => sparse; we allocate it last so that we can deallocate it + unsigned int* revremap = allocator.allocate(vertex_count); + for (size_t i = 0; i < index_count; ++i) { - if (filter[indices[i]] == 1) + unsigned int index = indices[i]; + + if (filter[index] == 1) { remap[offset] = indices[i]; - filter[indices[i]] = 0; - revremap[indices[i]] = unsigned(offset); + revremap[index] = unsigned(offset); indices[i] = unsigned(offset); + filter[index] = 0; offset++; } else { - indices[i] = revremap[indices[i]]; + indices[i] = revremap[index]; } } + allocator.deallocate(revremap); + + assert(offset == unique); *out_vertex_count = unique; + return remap; } From 3a49202cd64e910830496ea8120341764b5a8a93 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 13 Jun 2024 23:41:20 -0700 Subject: [PATCH 105/581] simplify: Fix MSVC warning --- src/simplifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 6c016f7b3d..cb6f3a7da2 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -442,7 +442,7 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat for (size_t i = 0; i < vertex_count; ++i) { - unsigned int ri = sparse_remap ? sparse_remap[i] : i; + unsigned int ri = sparse_remap ? sparse_remap[i] : unsigned(i); const float* v = vertex_positions_data + ri * vertex_stride_float; if (result) From c6737f6c2f499386829d70451f29a2cea3e4bada Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 08:51:21 -0700 Subject: [PATCH 106/581] simplify: Use a bit set for sparse remap computation We have two parts of buildSparseRemap that are still dependent on the number of vertices wrt complexity, filter clearing and revremap allocation. We could replace revremap with a hash map if a large allocation proves to be problematic, but it also might work fine in practice - whereas filter[] clearing is a cost we must pay and for small subsets of large meshes this can be 20% of the entire simplification. To fix this we now use a bit set which is 8x cheaper to clear (the actual addressing gets more expensive but it's a fraction of the cost due to sparsity assumption). --- src/simplifier.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index cb6f3a7da2..fcb0296fb8 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -212,15 +212,18 @@ static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const f static unsigned int* buildSparseRemap(unsigned int* indices, size_t index_count, size_t vertex_count, size_t* out_vertex_count, meshopt_Allocator& allocator) { - unsigned char* filter = allocator.allocate(vertex_count); - memset(filter, 0, vertex_count); + // use a bit set to compute the precise number of unique vertices + unsigned char* filter = allocator.allocate((vertex_count + 7) / 8); + memset(filter, 0, (vertex_count + 7) / 8); size_t unique = 0; for (size_t i = 0; i < index_count; ++i) { - assert(indices[i] < vertex_count); - unique += filter[indices[i]] == 0; - filter[indices[i]] = 1; + unsigned int index = indices[i]; + assert(index < vertex_count); + + unique += (filter[index / 8] & (1 << (index % 8))) == 0; + filter[index / 8] |= 1 << (index % 8); } unsigned int* remap = allocator.allocate(unique); @@ -229,16 +232,18 @@ static unsigned int* buildSparseRemap(unsigned int* indices, size_t index_count, // temporary map dense => sparse; we allocate it last so that we can deallocate it unsigned int* revremap = allocator.allocate(vertex_count); + // fill remap, using revremap as a helper, and rewrite indices in the same pass + // note: we use filter[] here to avoid initializing revremap for performance for (size_t i = 0; i < index_count; ++i) { unsigned int index = indices[i]; - if (filter[index] == 1) + if ((filter[index / 8] & (1 << (index % 8))) != 0) { remap[offset] = indices[i]; revremap[index] = unsigned(offset); indices[i] = unsigned(offset); - filter[index] = 0; + filter[index / 8] &= ~(1 << (index % 8)); offset++; } else From 0836a67850ab160abe5a5d0657da64a56552cfab Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 08:54:32 -0700 Subject: [PATCH 107/581] simplify: Fix vertex_lock access when sparse simplification is used classifyVertices references the input vertex_lock[] which is indexed using dense vertex indices so it needs to remap the access index on the fly as well. --- src/simplifier.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index fcb0296fb8..2878830716 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -307,7 +307,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int return false; } -static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_lock, unsigned int options) +static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_lock, const unsigned int* sparse_remap, unsigned int options) { memset(loop, -1, vertex_count * sizeof(unsigned int)); memset(loopback, -1, vertex_count * sizeof(unsigned int)); @@ -353,7 +353,7 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned { if (remap[i] == i) { - if (vertex_lock && vertex_lock[i]) + if (vertex_lock && vertex_lock[sparse_remap ? sparse_remap[i] : i]) { // vertex is explicitly locked result[i] = Kind_Locked; @@ -1570,7 +1570,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic unsigned char* vertex_kind = allocator.allocate(vertex_count); unsigned int* loop = allocator.allocate(vertex_count); unsigned int* loopback = allocator.allocate(vertex_count); - classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, vertex_lock, options); + classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, vertex_lock, sparse_remap, options); #if TRACE size_t unique_positions = 0; From 7fabea9b72f9f0ed340ca57f681471c78a475878 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 11:28:50 -0700 Subject: [PATCH 108/581] simplify: Add SimplifyErrorAbsolute flag to treat error as absolute When using sparse simplification, the error is treated as relative to the mesh subset. This is a performance requirement as computing the full mesh extents is too expensive when the subset is small relative to the mesh, but it means that it can be difficult to rely on exact error metrics. There are also cases in general, when not using sparse simplification, when an absolute error is more convenient. These can be achieved right now via meshopt_simplifyScale but that is an extra step that is not always necessary. With this change, when meshopt_SimplifyErrorAbsolute flag is used, we treat the error limit and the output error as an absolute distance (in mesh coordinates), and convert it to/from relative using the internal scale factor. --- src/meshoptimizer.h | 2 ++ src/simplifier.cpp | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index a01e6cf4fd..bb78cf284b 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -332,6 +332,8 @@ enum meshopt_SimplifyLockBorder = 1 << 0, /* Improve simplification performance assuming input indices are a sparse subset of the mesh. Note that error becomes relative to subset extents. */ meshopt_SimplifySparse = 1 << 1, + /* Treat error limit and resulting error as absolute instead of relative to mesh extents. */ + meshopt_SimplifyErrorAbsolute = 1 << 2, }; /** diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 2878830716..79ad69f91a 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -1539,7 +1539,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(target_index_count <= index_count); - assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse)) == 0); + assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute)) == 0); assert(vertex_attributes_stride >= attribute_count * sizeof(float) && vertex_attributes_stride <= 256); assert(vertex_attributes_stride % sizeof(float) == 0); assert(attribute_count <= kMaxAttributes); @@ -1588,7 +1588,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic #endif Vector3* vertex_positions = allocator.allocate(vertex_count); - rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride, sparse_remap); + float vertex_scale = rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride, sparse_remap); float* vertex_attributes = NULL; @@ -1634,7 +1634,8 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic float result_error = 0; // target_error input is linear; we need to adjust it to match quadricError units - float error_limit = target_error * target_error; + float error_scale = (options & meshopt_SimplifyErrorAbsolute) ? vertex_scale : 1.f; + float error_limit = (target_error * target_error) / (error_scale * error_scale); while (result_count > target_index_count) { @@ -1700,7 +1701,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic // result_error is quadratic; we need to remap it back to linear if (out_result_error) - *out_result_error = sqrtf(result_error); + *out_result_error = sqrtf(result_error) * error_scale; return result_count; } From 0fdca1ec8cfff1907c7e28426cc967e7507c9ced Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 11:45:26 -0700 Subject: [PATCH 109/581] demo: Use meshopt_SimplifyErrorAbsolute in simplifyClusters Previously we couldn't really guarantee a sensible error bound or display the resulting deviation, but meshopt_SimplifyErrorAbsolute together with meshopt_simplifyScale makes it easy, so we incorporate that into simplifyClusters. --- demo/main.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index 665951aa88..e923d2fe50 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -658,9 +658,13 @@ void simplifyClusters(const Mesh& mesh, float threshold = 0.2f) double middle = timestamp(); + float scale = meshopt_simplifyScale(&mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex)); + std::vector lod; lod.reserve(mesh.indices.size()); + float error = 0.f; + for (size_t i = 0; i < meshlets.size(); ++i) { const meshopt_Meshlet& m = meshlets[i]; @@ -670,10 +674,14 @@ void simplifyClusters(const Mesh& mesh, float threshold = 0.2f) for (size_t j = 0; j < m.triangle_count * 3; ++j) lod.push_back(meshlet_vertices[m.vertex_offset + meshlet_triangles[m.triangle_offset + j]]); - unsigned int options = meshopt_SimplifyLockBorder | meshopt_SimplifySparse; + unsigned int options = meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute; + float cluster_target_error = 1e-2f * scale; size_t cluster_target = size_t(float(m.triangle_count) * threshold) * 3; - size_t cluster_size = meshopt_simplify(&lod[cluster_offset], &lod[cluster_offset], m.triangle_count * 3, &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), cluster_target, threshold, options, 0); + float cluster_error = 0.f; + size_t cluster_size = meshopt_simplify(&lod[cluster_offset], &lod[cluster_offset], m.triangle_count * 3, &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), cluster_target, cluster_target_error, options, &cluster_error); + + error = cluster_error > error ? cluster_error : error; // simplified cluster is available in lod[cluster_offset..cluster_offset + cluster_size] lod.resize(cluster_offset + cluster_size); @@ -681,9 +689,10 @@ void simplifyClusters(const Mesh& mesh, float threshold = 0.2f) double end = timestamp(); - printf("%-9s: %d triangles => %d triangles in %.2f msec, clusterized in %.2f msec\n", + printf("%-9s: %d triangles => %d triangles (%.2f%% deviation) in %.2f msec, clusterized in %.2f msec\n", "SimplifyN", // N for Nanite int(mesh.indices.size() / 3), int(lod.size() / 3), + error / scale * 100, (end - middle) * 1000, (middle - start) * 1000); } @@ -1291,6 +1300,7 @@ void processDev(const char* path) if (!loadMesh(mesh, path)) return; + simplify(mesh); simplifyClusters(mesh); } From f64ba55900f4791378a371b68e20db24b77ca6f5 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 11:55:35 -0700 Subject: [PATCH 110/581] demo: Add a test for meshopt_SimplifyErrorAbsolute We collapse a center vertex which introduces an error and check that the error is close to what we would expect. Note that the distance the vertex travels here is 1.0f, not 0.85f, but the errors are evaluated as distances to triangles which makes it smaller. --- demo/tests.cpp | 53 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/demo/tests.cpp b/demo/tests.cpp index 7c94ba935c..53a9e6f28b 100644 --- a/demo/tests.cpp +++ b/demo/tests.cpp @@ -1188,15 +1188,15 @@ static void simplifyAttr() static void simplifyLockFlags() { float vb[] = { - 0.000000f, 0.000000f, 0.000000f, - 0.000000f, 1.000000f, 0.000000f, - 0.000000f, 2.000000f, 0.000000f, - 1.000000f, 0.000000f, 0.000000f, - 1.000000f, 1.000000f, 0.000000f, - 1.000000f, 2.000000f, 0.000000f, - 2.000000f, 0.000000f, 0.000000f, - 2.000000f, 1.000000f, 0.000000f, - 2.000000f, 2.000000f, 0.000000f, // clang-format :-/ + 0, 0, 0, + 0, 1, 0, + 0, 2, 0, + 1, 0, 0, + 1, 1, 0, + 1, 2, 0, + 2, 0, 0, + 2, 1, 0, + 2, 2, 0, // clang-format :-/ }; unsigned char lock[9] = { @@ -1233,6 +1233,40 @@ static void simplifyLockFlags() assert(memcmp(ib, expected, sizeof(expected)) == 0); } +static void simplifyErrorAbsolute() +{ + float vb[] = { + 0, 0, 0, + 0, 1, 0, + 0, 2, 0, + 1, 0, 0, + 1, 1, 1, + 1, 2, 0, + 2, 0, 0, + 2, 1, 0, + 2, 2, 0, // clang-format :-/ + }; + + // 0 1 2 + // 3 4 5 + // 6 7 8 + + unsigned int ib[] = { + 0, 1, 3, + 3, 1, 4, + 1, 2, 4, + 4, 2, 5, + 3, 4, 6, + 6, 4, 7, + 4, 5, 7, + 7, 5, 8, // clang-format :-/ + }; + + float error = 0.f; + assert(meshopt_simplify(ib, ib, 24, vb, 9, 12, 18, 2.f, meshopt_SimplifyLockBorder | meshopt_SimplifyErrorAbsolute, &error) == 18); + assert(fabsf(error - 0.85f) < 0.01f); +} + static void adjacency() { // 0 1/4 @@ -1448,6 +1482,7 @@ void runTests() simplifyLockBorder(); simplifyAttr(); simplifyLockFlags(); + simplifyErrorAbsolute(); adjacency(); tessellation(); From 5a2bd4e7964ea5dea486cd8cb39aad49c44cc77e Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 14:08:49 -0700 Subject: [PATCH 111/581] js: Expose new simplification options Note that this change doesn't rebuild the Wasm bundle; the options should just work once that is done. --- js/meshopt_simplifier.js | 2 ++ js/meshopt_simplifier.module.d.ts | 2 +- js/meshopt_simplifier.module.js | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 3daeb3808f..73590683ac 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -155,6 +155,8 @@ var MeshoptSimplifier = (function() { var simplifyOptions = { LockBorder: 1, + Sparse: 2, + ErrorAbsolute: 4, }; return { diff --git a/js/meshopt_simplifier.module.d.ts b/js/meshopt_simplifier.module.d.ts index 7e95ad83d8..b0131756b6 100644 --- a/js/meshopt_simplifier.module.d.ts +++ b/js/meshopt_simplifier.module.d.ts @@ -1,6 +1,6 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -export type Flags = "LockBorder"; +export type Flags = "LockBorder" | "Sparse" | "ErrorAbsolute"; export const MeshoptSimplifier: { supported: boolean; diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index a4ff5f1fe8..5b540a4a52 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -154,6 +154,8 @@ var MeshoptSimplifier = (function() { var simplifyOptions = { LockBorder: 1, + Sparse: 2, + ErrorAbsolute: 4, }; return { From b5bc216e061e472d62301143d18a8efb75a3973f Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 14:26:02 -0700 Subject: [PATCH 112/581] demo: Add a test for sparse simplification The test needs to check that positions, attributes and lock flags are all addressed using proper indexing. We do assume that collapses are going in a specific direction (the input data technically permits two collapse directions for each test), if this becomes a problem due to fp instabilities we can tweak the input data then. --- demo/tests.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/demo/tests.cpp b/demo/tests.cpp index 53a9e6f28b..83e2b25a64 100644 --- a/demo/tests.cpp +++ b/demo/tests.cpp @@ -1233,6 +1233,77 @@ static void simplifyLockFlags() assert(memcmp(ib, expected, sizeof(expected)) == 0); } +static void simplifySparse() +{ + float vb[] = { + 0, 0, 100, + 0, 1, 0, + 0, 2, 100, + 1, 0, 0.1f, + 1, 1, 0.1f, + 1, 2, 0.1f, + 2, 0, 100, + 2, 1, 0, + 2, 2, 100, // clang-format :-/ + }; + + float vba[] = { + 100, + 0.5f, + 100, + 0.5f, + 0.5f, + 0, + 100, + 0.5f, + 100, // clang-format :-/ + }; + + float aw[] = { + 0.2f}; + + unsigned char lock[9] = { + 8, 1, 8, + 1, 0, 1, + 8, 1, 8, // clang-format :-/ + }; + + // 1 + // 3 4 5 + // 7 + + unsigned int ib[] = { + 3, 1, 4, + 1, 5, 4, + 3, 4, 7, + 4, 5, 7, // clang-format :-/ + }; + + unsigned int res[12]; + + // vertices 3-4-5 are slightly elevated along Z which guides the collapses when only using geometry + unsigned int expected[] = { + 1, 5, 3, + 3, 5, 7, // clang-format :-/ + }; + + assert(meshopt_simplify(res, ib, 12, vb, 9, 12, 6, 1e-3f, meshopt_SimplifySparse) == 6); + assert(memcmp(res, expected, sizeof(expected)) == 0); + + // vertices 1-4-7 have a crease in the attribute value which guides the collapses the opposite way when weighing attributes sufficiently + unsigned int expecteda[] = { + 3, 1, 7, + 1, 5, 7, // clang-format :-/ + }; + + assert(meshopt_simplifyWithAttributes(res, ib, 12, vb, 9, 12, vba, sizeof(float), aw, 1, lock, 6, 1e-1f, meshopt_SimplifySparse) == 6); + assert(memcmp(res, expecteda, sizeof(expecteda)) == 0); + + // a final test validates that destination can alias when using sparsity + assert(meshopt_simplify(ib, ib, 12, vb, 9, 12, 6, 1e-3f, meshopt_SimplifySparse) == 6); + assert(memcmp(ib, expected, sizeof(expected)) == 0); +} + static void simplifyErrorAbsolute() { float vb[] = { @@ -1482,6 +1553,7 @@ void runTests() simplifyLockBorder(); simplifyAttr(); simplifyLockFlags(); + simplifySparse(); simplifyErrorAbsolute(); adjacency(); From b91edfcee82c2882a6ddff6cad7cc6fe88f2b003 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 20:17:07 -0700 Subject: [PATCH 113/581] demo: Add simplifyClusters to the default set of pipelines This helps to test sparse simplification on a large variety of meshes. Drive-by: fix simplifyPoints under address sanitizer when the number of points was below the threshold so &indices[0] would be out of bounds. --- demo/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/demo/main.cpp b/demo/main.cpp index e923d2fe50..f93bf34e86 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -522,6 +522,8 @@ void simplifyPoints(const Mesh& mesh, float threshold = 0.2f) double start = timestamp(); size_t target_vertex_count = size_t(mesh.vertices.size() * threshold); + if (target_vertex_count == 0) + return; std::vector indices(target_vertex_count); indices.resize(meshopt_simplifyPoints(&indices[0], &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), NULL, 0, 0, target_vertex_count)); @@ -1286,6 +1288,7 @@ void process(const char* path) simplifySloppy(mesh); simplifyComplete(mesh); simplifyPoints(mesh); + simplifyClusters(mesh); spatialSort(mesh); spatialSortTriangles(mesh); From 54702d77374f73dd47ef3fd329bb342cdd864241 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 15 Jun 2024 09:17:35 -0700 Subject: [PATCH 114/581] simplify: Use a hash map to generate sparse remap Instead of using a large uninitialized allocation, we now use a hash table. Under the assumption that a mesh subset is much smaller, we were relying on the efficiency of repeatedly reallocating a large uninitialized segment of memory, which worked well on some systems (Linux) but not as much on others (Windows). Instead, we now minimize the allocation size. This ends up a little slower when the sparsity assumption does not hold, as we no longer use direct indexing. To minimize the impact, we use a hash function that reduces the amount of avalanche so that sequential indices have fewer hash conflicts; it might also make sense to use an identity function here, or a small multiplicative constant. To minimize the impact further, we don't store pairs in the map, and just store the new index; when doing a lookup, due to the unique construction of the hasher we can lookup the dense index despite the fact that the map only stores sparse indices. --- src/simplifier.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 79ad69f91a..1f6f8ab183 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -136,6 +136,21 @@ struct PositionHasher } }; +struct RemapHasher +{ + unsigned int* remap; + + size_t hash(unsigned int id) const + { + return id * 0x5bd1e995; + } + + bool equal(unsigned int lhs, unsigned int rhs) const + { + return remap[lhs] == rhs; + } +}; + static size_t hashBuckets2(size_t count) { size_t buckets = 1; @@ -230,26 +245,27 @@ static unsigned int* buildSparseRemap(unsigned int* indices, size_t index_count, size_t offset = 0; // temporary map dense => sparse; we allocate it last so that we can deallocate it - unsigned int* revremap = allocator.allocate(vertex_count); + size_t revremap_size = hashBuckets2(unique); + unsigned int* revremap = allocator.allocate(revremap_size); + memset(revremap, -1, revremap_size * sizeof(unsigned int)); // fill remap, using revremap as a helper, and rewrite indices in the same pass - // note: we use filter[] here to avoid initializing revremap for performance + RemapHasher hasher = {remap}; + for (size_t i = 0; i < index_count; ++i) { unsigned int index = indices[i]; - if ((filter[index / 8] & (1 << (index % 8))) != 0) + unsigned int* entry = hashLookup2(revremap, revremap_size, hasher, index, ~0u); + + if (*entry == ~0u) { - remap[offset] = indices[i]; - revremap[index] = unsigned(offset); - indices[i] = unsigned(offset); - filter[index / 8] &= ~(1 << (index % 8)); + remap[offset] = index; + *entry = unsigned(offset); offset++; } - else - { - indices[i] = revremap[index]; - } + + indices[i] = *entry; } allocator.deallocate(revremap); From 924eacad1962462e11b3b4a5e7a9bb0fae419900 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 14 Jun 2024 09:28:28 -0700 Subject: [PATCH 115/581] simplify: Work around MSVC static analysis false positive We intentionally use bitwise & here to reduce branch mispredictions; if the result is int, MSVC does not emit a warning. --- src/simplifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index a84b33270a..83660dbe6b 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -1310,7 +1310,7 @@ static void fillCellQuadrics(Quadric* cell_quadrics, const unsigned int* indices unsigned int c1 = vertex_cells[i1]; unsigned int c2 = vertex_cells[i2]; - bool single_cell = (c0 == c1) & (c0 == c2); + int single_cell = (c0 == c1) & (c0 == c2); Quadric Q; quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], single_cell ? 3.f : 1.f); From 5158851e86707c00e142103325bd117ffb083a1d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 17 Jun 2024 12:38:16 -0700 Subject: [PATCH 116/581] Adjust ternary operators to conform to clang-format clang-format uses rules to format nested ternaries that, in absence of a column limit, result in odd formatting unless the nested ternaries are parenthesized. Until this is fixed, we'd need to change the formatting style to avoid excessive line breaks when reformatting the entire codebase. --- gltf/gltfpack.cpp | 2 +- gltf/json.cpp | 2 +- gltf/write.cpp | 2 +- src/clusterizer.cpp | 2 +- src/indexcodec.cpp | 8 ++++---- src/simplifier.cpp | 8 ++++---- src/stripifier.cpp | 2 +- src/vertexcodec.cpp | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index d42371d016..f3156d3e38 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -1184,7 +1184,7 @@ Settings defaults() template T clamp(T v, T min, T max) { - return v < min ? min : v > max ? max : v; + return v < min ? min : (v > max ? max : v); } unsigned int textureMask(const char* arg) diff --git a/gltf/json.cpp b/gltf/json.cpp index 5ab3310185..92062d0703 100644 --- a/gltf/json.cpp +++ b/gltf/json.cpp @@ -60,7 +60,7 @@ void appendJson(std::string& s, const char* data) break; case Quoted: - state = (ch == '"') ? None : (ch == '\\') ? Escape : Quoted; + state = (ch == '"') ? None : (ch == '\\' ? Escape : Quoted); break; case Escape: diff --git a/gltf/write.cpp b/gltf/write.cpp index be6a492fff..13f2f3ad58 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -1471,7 +1471,7 @@ void writeAnimation(std::string& json, std::vector& views, std::stri comma(json_samplers); append(json_samplers, "{\"input\":"); - append(json_samplers, range ? range_accr : track.constant ? pose_accr : time_accr); + append(json_samplers, range ? range_accr : (track.constant ? pose_accr : time_accr)); append(json_samplers, ",\"output\":"); append(json_samplers, data_accr); if (track.interpolation == cgltf_interpolation_type_step) diff --git a/src/clusterizer.cpp b/src/clusterizer.cpp index be8c2c2db1..52fe5a362c 100644 --- a/src/clusterizer.cpp +++ b/src/clusterizer.cpp @@ -441,7 +441,7 @@ static size_t kdtreeBuild(size_t offset, KDNode* nodes, size_t node_count, const } // split axis is one where the variance is largest - unsigned int axis = vars[0] >= vars[1] && vars[0] >= vars[2] ? 0 : vars[1] >= vars[2] ? 1 : 2; + unsigned int axis = (vars[0] >= vars[1] && vars[0] >= vars[2]) ? 0 : (vars[1] >= vars[2] ? 1 : 2); float split = mean[axis]; size_t middle = kdtreePartition(indices, count, points, stride, axis, split); diff --git a/src/indexcodec.cpp b/src/indexcodec.cpp index 4cc2fea63a..b300460052 100644 --- a/src/indexcodec.cpp +++ b/src/indexcodec.cpp @@ -33,7 +33,7 @@ static int rotateTriangle(unsigned int a, unsigned int b, unsigned int c, unsign { (void)a; - return (b == next) ? 1 : (c == next) ? 2 : 0; + return (b == next) ? 1 : (c == next ? 2 : 0); } static int getEdgeFifo(EdgeFifo fifo, unsigned int a, unsigned int b, unsigned int c, size_t offset) @@ -217,7 +217,7 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons int fe = fer >> 2; int fc = getVertexFifo(vertexfifo, c, vertexfifooffset); - int fec = (fc >= 1 && fc < fecmax) ? fc : (c == next) ? (next++, 0) : 15; + int fec = (fc >= 1 && fc < fecmax) ? fc : (c == next ? (next++, 0) : 15); if (fec == 15 && version >= 1) { @@ -267,8 +267,8 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons // after rotation, a is almost always equal to next, so we don't waste bits on FIFO encoding for a int fea = (a == next) ? (next++, 0) : 15; - int feb = (fb >= 0 && fb < 14) ? (fb + 1) : (b == next) ? (next++, 0) : 15; - int fec = (fc >= 0 && fc < 14) ? (fc + 1) : (c == next) ? (next++, 0) : 15; + int feb = (fb >= 0 && fb < 14) ? fb + 1 : (b == next ? (next++, 0) : 15); + int fec = (fc >= 0 && fc < 14) ? fc + 1 : (c == next ? (next++, 0) : 15); // we encode feb & fec in 4 bits using a table if possible, and as a full byte otherwise unsigned char codeaux = (unsigned char)((feb << 4) | fec); diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 112bfb3125..84efaab6e7 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -1782,14 +1782,14 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind // we clamp the prediction of the grid size to make sure that the search converges int grid_size = next_grid_size; - grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size; + grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid ? max_grid - 1 : grid_size); computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size); size_t triangles = countTriangles(vertex_ids, indices, index_count); #if TRACE printf("pass %d (%s): grid size %d, triangles %d, %s\n", - pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" : "binary", + pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses ? "lerp" : "binary"), grid_size, int(triangles), (triangles <= target_index_count / 3) ? "under" : "over"); #endif @@ -1914,14 +1914,14 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos // we clamp the prediction of the grid size to make sure that the search converges int grid_size = next_grid_size; - grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size; + grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid ? max_grid - 1 : grid_size); computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size); size_t vertices = countVertexCells(table, table_size, vertex_ids, vertex_count); #if TRACE printf("pass %d (%s): grid size %d, vertices %d, %s\n", - pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" : "binary", + pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses ? "lerp" : "binary"), grid_size, int(vertices), (vertices <= target_vertex_count) ? "under" : "over"); #endif diff --git a/src/stripifier.cpp b/src/stripifier.cpp index 8ce17ef3dc..d57fb512bf 100644 --- a/src/stripifier.cpp +++ b/src/stripifier.cpp @@ -18,7 +18,7 @@ static unsigned int findStripFirst(const unsigned int buffer[][3], unsigned int for (size_t i = 0; i < buffer_size; ++i) { unsigned int va = valence[buffer[i][0]], vb = valence[buffer[i][1]], vc = valence[buffer[i][2]]; - unsigned int v = (va < vb && va < vc) ? va : (vb < vc) ? vb : vc; + unsigned int v = (va < vb && va < vc) ? va : (vb < vc ? vb : vc); if (v < iv) { diff --git a/src/vertexcodec.cpp b/src/vertexcodec.cpp index 8ab0662d88..94f7a1adc2 100644 --- a/src/vertexcodec.cpp +++ b/src/vertexcodec.cpp @@ -245,7 +245,7 @@ static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end, } } - int bitslog2 = (best_bits == 1) ? 0 : (best_bits == 2) ? 1 : (best_bits == 4) ? 2 : 3; + int bitslog2 = (best_bits == 1) ? 0 : (best_bits == 2 ? 1 : (best_bits == 4 ? 2 : 3)); assert((1 << bitslog2) == best_bits); size_t header_offset = i / kByteGroupSize; From 79640b8ab37bc61e1f585c19f819769f727ac9a6 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 19 Jun 2024 13:44:46 -0700 Subject: [PATCH 117/581] tools: Add initial basic texture analysis script In order to calibrate the texture compression settings better, we need a way to analyze a few representative files and plot the dependency between quality/size and compression parameters. This version focuses on UASTC and UASTC RDO lambda specifically as it's the most sensitive parameter. --- tools/bitmask.py | 0 tools/gltfbasis.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) mode change 100755 => 100644 tools/bitmask.py create mode 100644 tools/gltfbasis.py diff --git a/tools/bitmask.py b/tools/bitmask.py old mode 100755 new mode 100644 diff --git a/tools/gltfbasis.py b/tools/gltfbasis.py new file mode 100644 index 0000000000..806afa7a7c --- /dev/null +++ b/tools/gltfbasis.py @@ -0,0 +1,61 @@ +#!/usr/bin/python3 + +import argparse +import matplotlib.pyplot as plt +import os +import os.path +import re +import subprocess + +argp = argparse.ArgumentParser() +argp.add_argument('--basisu', type=str, required=True) +argp.add_argument('files', type=str, nargs='+') +args = argp.parse_args() + +def compress(path, flags): + temp_path = "/dev/null" if os.name == "posix" else "NUL" + output = subprocess.check_output([args.basisu, "-file", path, "-output_file", temp_path, "-stats", "-ktx2"] + flags) + for line in output.splitlines(): + if m := re.match(r".*source image.*?(\d+)x(\d+)", line.decode()): + pixels = int(m.group(1)) * int(m.group(2)) + elif m := re.match(r".*Compression succeeded.*size (\d+) bytes", line.decode()): + bytes = int(m.group(1)) + elif m := re.match(r"\.basis RGB Avg:.*RMS: (\d+\.\d+) PSNR: (\d+\.\d+)", line.decode()): + rms = float(m.group(1)) + psnr = float(m.group(2)) + + return {'path': path, 'bpp': bytes * 8 / pixels, 'rms': rms, 'psnr': psnr} + +def uastc_stats(path): + results = [] + for rdo_l in range(0, 20): + flags = ["-uastc", "-uastc_level", "1", "-uastc_rdo_l", str(rdo_l / 5), "-uastc_rdo_d", "1024"] + res = compress(path, flags) + res['rdo_l'] = rdo_l / 5 + results.append(res) + return results + +plt.figure(figsize=(15, 5)) + +for path in args.files: + print('Processing', path) + results = uastc_stats(path) + name = os.path.basename(path) + plt.subplot(1, 3, 1) + plt.plot([r['rdo_l'] for r in results], [r['bpp'] for r in results], label=name) + plt.subplot(1, 3, 2) + plt.plot([r['rdo_l'] for r in results], [r['rms'] for r in results], label=name) + plt.subplot(1, 3, 3) + plt.plot([r['rdo_l'] for r in results], [r['psnr'] for r in results], label=name) + +plt.subplot(1, 3, 1) +plt.title('bpp') +plt.legend() +plt.subplot(1, 3, 2) +plt.title('rms') +plt.legend() +plt.subplot(1, 3, 3) +plt.title('psnr') +plt.legend() + +plt.savefig('basisu.png') From 4e0cefd96b79bab3d5759b6e5484759ef22f1fa3 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 19 Jun 2024 14:13:12 -0700 Subject: [PATCH 118/581] tools: Add ETC1S baseline data to gltfbasis.py Without this it's difficult to judge the relative improvement/regression as the values naturally vary per image. --- tools/gltfbasis.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/gltfbasis.py b/tools/gltfbasis.py index 806afa7a7c..af8bd8dd1e 100644 --- a/tools/gltfbasis.py +++ b/tools/gltfbasis.py @@ -40,13 +40,17 @@ def uastc_stats(path): for path in args.files: print('Processing', path) results = uastc_stats(path) + etcbase = compress(path, ["-q", "192"]) name = os.path.basename(path) plt.subplot(1, 3, 1) - plt.plot([r['rdo_l'] for r in results], [r['bpp'] for r in results], label=name) + line, = plt.plot([r['rdo_l'] for r in results], [r['bpp'] for r in results], label=name) + plt.axhline(etcbase['bpp'], color=line.get_color(), linestyle='dotted') plt.subplot(1, 3, 2) - plt.plot([r['rdo_l'] for r in results], [r['rms'] for r in results], label=name) + line, = plt.plot([r['rdo_l'] for r in results], [r['rms'] for r in results], label=name) + plt.axhline(etcbase['rms'], color=line.get_color(), linestyle='dotted') plt.subplot(1, 3, 3) - plt.plot([r['rdo_l'] for r in results], [r['psnr'] for r in results], label=name) + line, = plt.plot([r['rdo_l'] for r in results], [r['psnr'] for r in results], label=name) + plt.axhline(etcbase['psnr'], color=line.get_color(), linestyle='dotted') plt.subplot(1, 3, 1) plt.title('bpp') From e36277e972abcb680837fb7c242abe57f9291949 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 19 Jun 2024 14:54:34 -0700 Subject: [PATCH 119/581] tools: Rework graph plotting and layout in gltfbasis We now use constrained layout to be able to put the combined legend outside of the plot area and switch to using Axes to make the code a little more robust. --- tools/gltfbasis.py | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/tools/gltfbasis.py b/tools/gltfbasis.py index af8bd8dd1e..03b6d86a80 100644 --- a/tools/gltfbasis.py +++ b/tools/gltfbasis.py @@ -26,7 +26,7 @@ def compress(path, flags): return {'path': path, 'bpp': bytes * 8 / pixels, 'rms': rms, 'psnr': psnr} -def uastc_stats(path): +def stats(path): results = [] for rdo_l in range(0, 20): flags = ["-uastc", "-uastc_level", "1", "-uastc_rdo_l", str(rdo_l / 5), "-uastc_rdo_d", "1024"] @@ -35,31 +35,25 @@ def uastc_stats(path): results.append(res) return results -plt.figure(figsize=(15, 5)) +fields = ['bpp', 'rms', 'psnr'] +fig, axs = plt.subplots(1, len(fields), layout='constrained') +fig.set_figwidth(5 * len(fields)) +lines = [] for path in args.files: print('Processing', path) - results = uastc_stats(path) + results = stats(path) etcbase = compress(path, ["-q", "192"]) - name = os.path.basename(path) - plt.subplot(1, 3, 1) - line, = plt.plot([r['rdo_l'] for r in results], [r['bpp'] for r in results], label=name) - plt.axhline(etcbase['bpp'], color=line.get_color(), linestyle='dotted') - plt.subplot(1, 3, 2) - line, = plt.plot([r['rdo_l'] for r in results], [r['rms'] for r in results], label=name) - plt.axhline(etcbase['rms'], color=line.get_color(), linestyle='dotted') - plt.subplot(1, 3, 3) - line, = plt.plot([r['rdo_l'] for r in results], [r['psnr'] for r in results], label=name) - plt.axhline(etcbase['psnr'], color=line.get_color(), linestyle='dotted') -plt.subplot(1, 3, 1) -plt.title('bpp') -plt.legend() -plt.subplot(1, 3, 2) -plt.title('rms') -plt.legend() -plt.subplot(1, 3, 3) -plt.title('psnr') -plt.legend() + for idx, field in enumerate(fields): + line, = axs[idx].plot([r['rdo_l'] for r in results], [r[field] for r in results]) + axs[idx].axhline(etcbase[field], color=line.get_color(), linestyle='dotted') + if idx == 0: + lines.append(line) + +for idx, field in enumerate(fields): + axs[idx].set_title(field) + +fig.legend(lines, [os.path.basename(path) for path in args.files], loc='outside right upper') plt.savefig('basisu.png') From 3d1cd8b5aa6e07807d0a9ccf65448e2f77a09b05 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 19 Jun 2024 15:05:50 -0700 Subject: [PATCH 120/581] tools: Parallelize texture processing in gltfbasis Use concurrent.futures to compress many texture variants at once, as individual texture processing doesn't saturate more than a couple cores via internal parallelism. --- tools/gltfbasis.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tools/gltfbasis.py b/tools/gltfbasis.py index 03b6d86a80..1345d187bc 100644 --- a/tools/gltfbasis.py +++ b/tools/gltfbasis.py @@ -1,6 +1,7 @@ #!/usr/bin/python3 import argparse +import concurrent.futures import matplotlib.pyplot as plt import os import os.path @@ -27,13 +28,19 @@ def compress(path, flags): return {'path': path, 'bpp': bytes * 8 / pixels, 'rms': rms, 'psnr': psnr} def stats(path): - results = [] - for rdo_l in range(0, 20): - flags = ["-uastc", "-uastc_level", "1", "-uastc_rdo_l", str(rdo_l / 5), "-uastc_rdo_d", "1024"] - res = compress(path, flags) - res['rdo_l'] = rdo_l / 5 - results.append(res) - return results + with concurrent.futures.ThreadPoolExecutor(16) as executor: + futures = [] + for i in range(0, 30): + rdo_l = i / 5 + flags = ["-uastc", "-uastc_level", "1", "-uastc_rdo_l", str(rdo_l), "-uastc_rdo_d", "1024"] + futures.append((executor.submit(compress, path, flags), rdo_l)) + concurrent.futures.wait([f for (f, r) in futures]) + results = [] + for future, rdo_l in futures: + res = future.result() + res['rdo_l'] = rdo_l + results.append(res) + return results fields = ['bpp', 'rms', 'psnr'] fig, axs = plt.subplots(1, len(fields), layout='constrained') From fd73be6053fa22b4c588f1fb054b443a85e15508 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 20 Jun 2024 18:24:49 -0700 Subject: [PATCH 121/581] tools: Add graph path argument to gltfbasis Also change the RDO lambda range to 0..5 --- tools/gltfbasis.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/gltfbasis.py b/tools/gltfbasis.py index 1345d187bc..d96298373a 100644 --- a/tools/gltfbasis.py +++ b/tools/gltfbasis.py @@ -10,6 +10,7 @@ argp = argparse.ArgumentParser() argp.add_argument('--basisu', type=str, required=True) +argp.add_argument('--graph', type=str, default="basisu.png") argp.add_argument('files', type=str, nargs='+') args = argp.parse_args() @@ -30,7 +31,7 @@ def compress(path, flags): def stats(path): with concurrent.futures.ThreadPoolExecutor(16) as executor: futures = [] - for i in range(0, 30): + for i in range(0, 26): rdo_l = i / 5 flags = ["-uastc", "-uastc_level", "1", "-uastc_rdo_l", str(rdo_l), "-uastc_rdo_d", "1024"] futures.append((executor.submit(compress, path, flags), rdo_l)) @@ -63,4 +64,4 @@ def stats(path): fig.legend(lines, [os.path.basename(path) for path in args.files], loc='outside right upper') -plt.savefig('basisu.png') +plt.savefig(args.graph) From a336c34d7b96974836e262d80f0ff5242cc0208d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 21 Jun 2024 10:08:32 -0700 Subject: [PATCH 122/581] tools: Add compression ratio and PSNR scatter plot to gltfbasis We now plot compression ratio in addition to bpp which is easier to read because it normalizes the RDO size impact, and a scatter plot of PSNR to ratio that allows to understand the trend lines for different textures better. --- tools/gltfbasis.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/gltfbasis.py b/tools/gltfbasis.py index d96298373a..cde9b0308b 100644 --- a/tools/gltfbasis.py +++ b/tools/gltfbasis.py @@ -37,15 +37,19 @@ def stats(path): futures.append((executor.submit(compress, path, flags), rdo_l)) concurrent.futures.wait([f for (f, r) in futures]) results = [] + bppbase = 0 for future, rdo_l in futures: res = future.result() + if rdo_l == 0: + bppbase = res['bpp'] res['rdo_l'] = rdo_l + res['ratio'] = res['bpp'] / bppbase results.append(res) return results -fields = ['bpp', 'rms', 'psnr'] -fig, axs = plt.subplots(1, len(fields), layout='constrained') -fig.set_figwidth(5 * len(fields)) +fields = ['bpp', 'rms', 'psnr', 'ratio'] +fig, axs = plt.subplots(1, len(fields) + 1, layout='constrained') +fig.set_figwidth(5 * (len(fields) + 1)) lines = [] for path in args.files: @@ -55,13 +59,18 @@ def stats(path): for idx, field in enumerate(fields): line, = axs[idx].plot([r['rdo_l'] for r in results], [r[field] for r in results]) - axs[idx].axhline(etcbase[field], color=line.get_color(), linestyle='dotted') + if field in etcbase: + axs[idx].axhline(etcbase[field], color=line.get_color(), linestyle='dotted') if idx == 0: lines.append(line) + axs[len(fields)].scatter([r['ratio'] for r in results], [r['psnr'] for r in results], color=line.get_color()) + for idx, field in enumerate(fields): axs[idx].set_title(field) +axs[len(fields)].set_title('psnr vs ratio') + fig.legend(lines, [os.path.basename(path) for path in args.files], loc='outside right upper') plt.savefig(args.graph) From 68ebd479e77c7a969835512620ea620076b692d2 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 21 Jun 2024 10:57:58 -0700 Subject: [PATCH 123/581] tools: Make ETC baseline opt in in gltfbasis These baselines are very helpful to analyze a small set of files but very distracting on a large set of files, so make this opt in via a command line argument. --- tools/gltfbasis.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/gltfbasis.py b/tools/gltfbasis.py index cde9b0308b..9fc8816667 100644 --- a/tools/gltfbasis.py +++ b/tools/gltfbasis.py @@ -11,6 +11,7 @@ argp = argparse.ArgumentParser() argp.add_argument('--basisu', type=str, required=True) argp.add_argument('--graph', type=str, default="basisu.png") +argp.add_argument('--etcbase', action='store_true') argp.add_argument('files', type=str, nargs='+') args = argp.parse_args() @@ -55,11 +56,11 @@ def stats(path): for path in args.files: print('Processing', path) results = stats(path) - etcbase = compress(path, ["-q", "192"]) + etcbase = compress(path, ["-q", "192"]) if args.etcbase else None for idx, field in enumerate(fields): line, = axs[idx].plot([r['rdo_l'] for r in results], [r[field] for r in results]) - if field in etcbase: + if etcbase and field in etcbase: axs[idx].axhline(etcbase[field], color=line.get_color(), linestyle='dotted') if idx == 0: lines.append(line) From 79a9be96c6e7f63ddf1ad2c40aff2f9c554f301a Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 21 Jun 2024 11:21:29 -0700 Subject: [PATCH 124/581] gltfpack: Rebalance texture quality table The main goal of this change is to tweak the UASTC RDO curve. The initial values here have been picked for early UASTC versions that used a different RDO algorithm, and haven't been revisited since. The new table makes it so that at tq 5, we use the same defaults as basisu (q=128 for ETC1 and l=1 for UASTC RDO), and tweak the table to be in general a little more aggressive for UASTC. We use different curves before l=1 and after as the expectation is that for earlier quality levels, the size is much more important than quality. The default lambda for tq=8 is a little larger now (0.4 vs 0.3) which will result in a small size improvement and still good quality by default. There's maybe a little more room for default lambda to be higher, but eg lambda=1 does not seem practical for normal maps on a range of production assets, so we keep the curve for tq=6..10 to be more quality focused. The new table is not based on a rigorous fitting of the actual quality/size curves, but the new tool gltfbasis.py can help find a more optimal table in the future. --- gltf/basisenc.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gltf/basisenc.cpp b/gltf/basisenc.cpp index c108094974..c415d2c5ef 100644 --- a/gltf/basisenc.cpp +++ b/gltf/basisenc.cpp @@ -26,15 +26,15 @@ struct BasisSettings }; static const BasisSettings kBasisSettings[10] = { - {1, 1, 0, 1.5f}, - {1, 6, 0, 1.f}, - {1, 20, 1, 1.0f}, - {1, 50, 1, 0.75f}, - {1, 90, 1, 0.5f}, - {1, 128, 1, 0.4f}, - {1, 160, 1, 0.34f}, - {1, 192, 1, 0.29f}, // default - {1, 224, 2, 0.26f}, + {1, 1, 0, 4.f}, + {1, 32, 0, 3.f}, + {1, 64, 1, 2.f}, + {1, 96, 1, 1.5f}, + {1, 128, 1, 1.f}, // quality arguments aligned with basisu defaults + {1, 150, 1, 0.8f}, + {1, 170, 1, 0.6f}, + {1, 192, 1, 0.4f}, // gltfpack defaults + {1, 224, 2, 0.2f}, {1, 255, 2, 0.f}, }; From b092eee9823cbc38ec8dd6107ff1dedcd3ac9bfa Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 22 Jun 2024 09:24:00 -0700 Subject: [PATCH 125/581] Update USERS.md Both Dota 2 and HL Alyx list meshoptimizer in third-party licenses in Steam distribution! --- USERS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USERS.md b/USERS.md index d92b19432e..2087152bda 100644 --- a/USERS.md +++ b/USERS.md @@ -10,6 +10,8 @@ If you are shipping a game that is using meshoptimizer, listing the library in t - [Baldur's Gate 3 (2023)](https://baldursgate3.game/) - [Cities: Skylines II (2023)](https://www.paradoxinteractive.com/games/cities-skylines-ii/about) - [Counter-Strike 2 (2023)](https://www.counter-strike.net/cs2) +- [Dota 2 (2013)](https://www.dota2.com/home) +- [Half-Life: Alyx (2020)](https://store.steampowered.com/app/546560/HalfLife_Alyx/) - [Jagged Alliance 3 (2023)](https://jaggedalliance3.thqnordic.com/) - [The Legend of Zelda: Tears of the Kingdom (2023)](https://zelda.nintendo.com/tears-of-the-kingdom/) - [Manifold Garden (2019)](https://manifold.garden) From 5e3f97ba5bba19f8e08ff8d0463ed0fef4dfd957 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 22 Jun 2024 09:28:36 -0700 Subject: [PATCH 126/581] extern: Update cgltf with EXT_texture_webp support This is currently pending a merge to upstream: https://github.com/jkuhlmann/cgltf/pull/253 --- extern/cgltf.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/extern/cgltf.h b/extern/cgltf.h index ac392aba43..36fd644e11 100644 --- a/extern/cgltf.h +++ b/extern/cgltf.h @@ -395,6 +395,8 @@ typedef struct cgltf_texture cgltf_sampler* sampler; cgltf_bool has_basisu; cgltf_image* basisu_image; + cgltf_bool has_webp; + cgltf_image* webp_image; cgltf_extras extras; cgltf_size extensions_count; cgltf_extension* extensions; @@ -4551,6 +4553,34 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok } } } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "EXT_texture_webp") == 0) + { + out_texture->has_webp = 1; + ++i; + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int num_properties = tokens[i].size; + ++i; + + for (int t = 0; t < num_properties; ++t) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) + { + ++i; + out_texture->webp_image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk)); + ++i; + } + else + { + i = cgltf_skip_json(tokens, i + 1); + } + if (i < 0) + { + return i; + } + } + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->extensions[out_texture->extensions_count++])); @@ -6561,6 +6591,7 @@ static int cgltf_fixup_pointers(cgltf_data* data) { CGLTF_PTRFIXUP(data->textures[i].image, data->images, data->images_count); CGLTF_PTRFIXUP(data->textures[i].basisu_image, data->images, data->images_count); + CGLTF_PTRFIXUP(data->textures[i].webp_image, data->images, data->images_count); CGLTF_PTRFIXUP(data->textures[i].sampler, data->samplers, data->samplers_count); } From 8ef1306a313c3242bd0ad9b043dd8a5ca23fd83b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 22 Jun 2024 09:29:49 -0700 Subject: [PATCH 127/581] gltfpack: Add basic support for EXT_texture_webp Similarly to KHR_texture_basisu appearing in the input, we now preserve webp images along with the extension if they are present in the input file. --- gltf/gltfpack.cpp | 3 +++ gltf/image.cpp | 1 + gltf/material.cpp | 9 ++++++--- gltf/write.cpp | 9 ++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index f3156d3e38..ee46fa6a71 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -454,6 +454,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output bool ext_instancing = false; bool ext_texture_transform = false; bool ext_texture_basisu = false; + bool ext_texture_webp = false; size_t accr_offset = 0; size_t node_offset = 0; @@ -512,6 +513,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output assert(textures[i].remap == int(texture_offset)); texture_offset++; ext_texture_basisu = ext_texture_basisu || texture.has_basisu; + ext_texture_webp = ext_texture_webp || texture.has_webp; } for (size_t i = 0; i < data->materials_count; ++i) @@ -838,6 +840,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output {"KHR_materials_variants", data->variants_count > 0, false}, {"KHR_lights_punctual", data->lights_count > 0, false}, {"KHR_texture_basisu", (!json_textures.empty() && settings.texture_ktx2) || ext_texture_basisu, true}, + {"EXT_texture_webp", ext_texture_webp, true}, {"EXT_mesh_gpu_instancing", ext_instancing, true}, }; diff --git a/gltf/image.cpp b/gltf/image.cpp index 129938a0e4..ca6d4c0f6b 100644 --- a/gltf/image.cpp +++ b/gltf/image.cpp @@ -8,6 +8,7 @@ static const char* kMimeTypes[][2] = { {"image/jpeg", ".jpeg"}, {"image/png", ".png"}, {"image/ktx2", ".ktx2"}, + {"image/webp", ".webp"}, }; static const char* inferMimeType(const char* path) diff --git a/gltf/material.cpp b/gltf/material.cpp index 0931b2e05b..68d5610c85 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -11,10 +11,10 @@ static bool areTexturesEqual(const cgltf_texture& lhs, const cgltf_texture& rhs) if (lhs.sampler != rhs.sampler) return false; - if (lhs.has_basisu != rhs.has_basisu) + if (lhs.basisu_image != rhs.basisu_image) return false; - if (lhs.basisu_image != rhs.basisu_image) + if (lhs.webp_image != rhs.webp_image) return false; return true; @@ -446,9 +446,12 @@ static const cgltf_image* getTextureImage(const cgltf_texture* texture) if (texture && texture->image) return texture->image; - if (texture && texture->has_basisu && texture->basisu_image) + if (texture && texture->basisu_image) return texture->basisu_image; + if (texture && texture->webp_image) + return texture->webp_image; + return NULL; } diff --git a/gltf/write.cpp b/gltf/write.cpp index 13f2f3ad58..429d0c4466 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -975,13 +975,20 @@ void writeTexture(std::string& json, const cgltf_texture& texture, const ImageIn } } - if (texture.has_basisu && texture.basisu_image) + if (texture.basisu_image) { comma(json); append(json, "\"extensions\":{\"KHR_texture_basisu\":{\"source\":"); append(json, size_t(texture.basisu_image - data->images)); append(json, "}}"); } + else if (texture.webp_image) + { + comma(json); + append(json, "\"extensions\":{\"EXT_texture_webp\":{\"source\":"); + append(json, size_t(texture.webp_image - data->images)); + append(json, "}}"); + } } void writeMeshAttributes(std::string& json, std::vector& views, std::string& json_accessors, size_t& accr_offset, const Mesh& mesh, int target, const QuantizationPosition& qp, const QuantizationTexture& qt, const Settings& settings) From dacb5fab5f639cb53f40147142c2b2e60e072c7a Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 22 Jun 2024 16:28:25 -0700 Subject: [PATCH 128/581] gltfpack: Implement support for WebP header parsing We only need an implementation for hasTransparency as getDimensions is only needed by texture compression pipeline which doesn't support anything but PNG/JPEG as an input. --- gltf/image.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/gltf/image.cpp b/gltf/image.cpp index ca6d4c0f6b..4eeb03013d 100644 --- a/gltf/image.cpp +++ b/gltf/image.cpp @@ -262,12 +262,44 @@ static bool hasTransparencyKtx2(const std::string& data) return false; } +static bool hasTransparencyWebP(const std::string& data) +{ + if (data.size() < 12 + 4 + 12) + return false; + + if (data.compare(0, 4, "RIFF") != 0) + return false; + if (data.compare(8, 4, "WEBP") != 0) + return false; + + // WebP data may use VP8L, VP8X or VP8 format, but VP8 does not support transparency + if (data.compare(12, 4, "VP8L") == 0) + { + if (unsigned(data[20]) != 0x2f) + return false; + + // width (14) | height (14) | alpha_is_used (1) | version_number(3) + unsigned int header = readInt32LE(data, 21); + return (header & (1 << 28)) != 0; + } + else if (data.compare(12, 4, "VP8X") == 0) + { + // zero (2) | icc (1) | alpha (1) | exif (1) | xmp (1) | animation (1) | zero (1) + unsigned char header = data[20]; + return (header & (1 << 4)) != 0; + } + + return false; +} + bool hasAlpha(const std::string& data, const char* mime_type) { if (strcmp(mime_type, "image/png") == 0) return hasTransparencyPng(data); else if (strcmp(mime_type, "image/ktx2") == 0) return hasTransparencyKtx2(data); + else if (strcmp(mime_type, "image/webp") == 0) + return hasTransparencyWebP(data); else return false; } From 5e468273a7873df56001d7ba98612d67dade945a Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 22 Jun 2024 16:30:10 -0700 Subject: [PATCH 129/581] gltfpack: Add references to image format standards The implementations have been written based on Wikipedia for PNG/JPEG, official Khronos specification for KTX2 and Google's specification for WebP. --- gltf/image.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gltf/image.cpp b/gltf/image.cpp index 4eeb03013d..972b4c441b 100644 --- a/gltf/image.cpp +++ b/gltf/image.cpp @@ -129,6 +129,7 @@ static int readInt32LE(const std::string& data, size_t offset) (unsigned((unsigned char)data[offset + 3]) << 24); } +// https://en.wikipedia.org/wiki/PNG#File_format static bool getDimensionsPng(const std::string& data, int& width, int& height) { if (data.size() < 8 + 8 + 13 + 4) @@ -147,6 +148,7 @@ static bool getDimensionsPng(const std::string& data, int& width, int& height) return true; } +// https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format#File_format_structure static bool getDimensionsJpeg(const std::string& data, int& width, int& height) { size_t offset = 0; @@ -190,6 +192,7 @@ static bool getDimensionsJpeg(const std::string& data, int& width, int& height) return false; } +// https://en.wikipedia.org/wiki/PNG#File_format static bool hasTransparencyPng(const std::string& data) { if (data.size() < 8 + 8 + 13 + 4) @@ -225,6 +228,7 @@ static bool hasTransparencyPng(const std::string& data) return false; } +// https://github.khronos.org/KTX-Specification/ktxspec.v2.html static bool hasTransparencyKtx2(const std::string& data) { if (data.size() < 12 + 17 * 4) @@ -262,6 +266,7 @@ static bool hasTransparencyKtx2(const std::string& data) return false; } +// https://developers.google.com/speed/webp/docs/riff_container static bool hasTransparencyWebP(const std::string& data) { if (data.size() < 12 + 4 + 12) From 1b3f30658036a7bd60ee250da7238a048aa4e27c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 22 Jun 2024 16:31:15 -0700 Subject: [PATCH 130/581] gltfpack: Add EXT_texture_webp to documentation as supported We don't support encoding webp images but we will now preserve them if they occur in the input. --- gltf/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/gltf/README.md b/gltf/README.md index ffe6d1e12f..4b278676ac 100644 --- a/gltf/README.md +++ b/gltf/README.md @@ -85,6 +85,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th - KHR_texture_transform - EXT_mesh_gpu_instancing - EXT_meshopt_compression +- EXT_texture_webp Even if the source file does not use extensions, gltfpack may use some extensions in the output file either by default or when certain options are used: From 1f42cf022014868369447af3a06b025c14a06507 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 24 Jun 2024 09:49:45 -0700 Subject: [PATCH 131/581] simplify: Make hasTriangleFlip predicate use an angle cutoff Instead of checking if the dot product is 0 or negative (90 degree limit on triangle rotations), use a cutoff of ~75 degrees. The motivation here is that meshes with complex curvature can end up flipping triangles through a series of collapses, and since we always evaluate flips compared to the current mesh we miss that. Technically this can happen even with a 75 degree limit, but in practice this solves cases of flips that have been reported before, and doesn't noticeably constrain simplification or slow it down. For numerical stability, we avoid dividing by the triangle areas (as they can be close to zero) and instead use the areas to compute a bound for dot product. Even if the area product underflows, we just get the same check that we used to have -- areas should be in [0..1] so there should be no risk of overflow. --- src/simplifier.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 84efaab6e7..e59b4afcd9 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -892,7 +892,13 @@ static bool hasTriangleFlip(const Vector3& a, const Vector3& b, const Vector3& c Vector3 nbc = {eb.y * ec.z - eb.z * ec.y, eb.z * ec.x - eb.x * ec.z, eb.x * ec.y - eb.y * ec.x}; Vector3 nbd = {eb.y * ed.z - eb.z * ed.y, eb.z * ed.x - eb.x * ed.z, eb.x * ed.y - eb.y * ed.x}; - return nbc.x * nbd.x + nbc.y * nbd.y + nbc.z * nbd.z <= 0; + float ndp = nbc.x * nbd.x + nbc.y * nbd.y + nbc.z * nbd.z; + float abc = nbc.x * nbc.x + nbc.y * nbc.y + nbc.z * nbc.z; + float abd = nbd.x * nbd.x + nbd.y * nbd.y + nbd.z * nbd.z; + + // scale is cos(angle); somewhat arbitrarily set to ~75 degrees + // note that the "pure" check is ndp <= 0 (90 degree cutoff) but that allows flipping through a series of close-to-90 collapses + return ndp <= 0.25f * sqrtf(abc * abd); } static bool hasTriangleFlips(const EdgeAdjacency& adjacency, const Vector3* vertex_positions, const unsigned int* collapse_remap, unsigned int i0, unsigned int i1) From f13503c8f1196e20bcfb1e67ea1e97b1d0ce98c7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 24 Jun 2024 10:37:29 -0700 Subject: [PATCH 132/581] Minor formatting changes meshoptimizer.h is not covered by clang-format and it had a couple cases where spaces were used for indentation instead of tabs. allocator.cpp *is* covered by clang-format and it's hitting the bug https://github.com/llvm/llvm-project/issues/34171; it's probably not worth trying to work around this for a single file that is basically never edited, but it's valuable to keep `make format` be a no-op. --- src/allocator.cpp | 2 +- src/meshoptimizer.h | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/allocator.cpp b/src/allocator.cpp index 072e8e51ac..12eda38729 100644 --- a/src/allocator.cpp +++ b/src/allocator.cpp @@ -1,7 +1,7 @@ // This file is part of meshoptimizer library; see meshoptimizer.h for version/license details #include "meshoptimizer.h" -void meshopt_setAllocator(void* (MESHOPTIMIZER_ALLOC_CALLCONV *allocate)(size_t), void (MESHOPTIMIZER_ALLOC_CALLCONV *deallocate)(void*)) +void meshopt_setAllocator(void*(MESHOPTIMIZER_ALLOC_CALLCONV* allocate)(size_t), void(MESHOPTIMIZER_ALLOC_CALLCONV* deallocate)(void*)) { meshopt_Allocator::Storage::allocate = allocate; meshopt_Allocator::Storage::deallocate = deallocate; diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index bb78cf284b..c6a1367b44 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -311,12 +311,12 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t cou */ enum meshopt_EncodeExpMode { - /* When encoding exponents, use separate values for each component (maximum quality) */ - meshopt_EncodeExpSeparate, - /* When encoding exponents, use shared value for all components of each vector (better compression) */ - meshopt_EncodeExpSharedVector, - /* When encoding exponents, use shared value for each component of all vectors (best compression) */ - meshopt_EncodeExpSharedComponent, + /* When encoding exponents, use separate values for each component (maximum quality) */ + meshopt_EncodeExpSeparate, + /* When encoding exponents, use shared value for all components of each vector (better compression) */ + meshopt_EncodeExpSharedVector, + /* When encoding exponents, use shared value for each component of all vectors (best compression) */ + meshopt_EncodeExpSharedComponent, }; MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterOct(void* destination, size_t count, size_t stride, int bits, const float* data); @@ -328,12 +328,12 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_ */ enum { - /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ - meshopt_SimplifyLockBorder = 1 << 0, - /* Improve simplification performance assuming input indices are a sparse subset of the mesh. Note that error becomes relative to subset extents. */ - meshopt_SimplifySparse = 1 << 1, - /* Treat error limit and resulting error as absolute instead of relative to mesh extents. */ - meshopt_SimplifyErrorAbsolute = 1 << 2, + /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ + meshopt_SimplifyLockBorder = 1 << 0, + /* Improve simplification performance assuming input indices are a sparse subset of the mesh. Note that error becomes relative to subset extents. */ + meshopt_SimplifySparse = 1 << 1, + /* Treat error limit and resulting error as absolute instead of relative to mesh extents. */ + meshopt_SimplifyErrorAbsolute = 1 << 2, }; /** @@ -973,10 +973,10 @@ inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_co template inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error) { - meshopt_IndexAdapter in(NULL, indices, index_count); - meshopt_IndexAdapter out(destination, NULL, index_count); + meshopt_IndexAdapter in(NULL, indices, index_count); + meshopt_IndexAdapter out(destination, NULL, index_count); - return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, result_error); + return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, result_error); } template From 4a75b2a952718d76118a3dac7f688e7593db0048 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 25 Jun 2024 09:57:52 -0700 Subject: [PATCH 133/581] Update version to 0.21 Also rebuild meshopt_simplifier wasm to accomodate recent improvements. --- CMakeLists.txt | 2 +- README.md | 4 ++-- gltf/gltfpack.h | 2 +- gltf/package.json | 2 +- js/meshopt_decoder.js | 2 +- js/meshopt_decoder.module.js | 2 +- js/meshopt_encoder.js | 2 +- js/meshopt_encoder.module.js | 2 +- js/meshopt_simplifier.js | 4 ++-- js/meshopt_simplifier.module.js | 4 ++-- js/package.json | 2 +- src/meshoptimizer.h | 4 ++-- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68aa59f5df..73b4a48f79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ if(POLICY CMP0092) cmake_policy(SET CMP0092 NEW) # Enables clean /W4 override for MSVC endif() -project(meshoptimizer VERSION 0.20 LANGUAGES CXX) +project(meshoptimizer VERSION 0.21 LANGUAGES CXX) option(MESHOPT_BUILD_DEMO "Build demo" OFF) option(MESHOPT_BUILD_GLTFPACK "Build gltfpack" OFF) diff --git a/README.md b/README.md index c42f7c18ff..6814e98413 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ The library provides a C and C++ interface for all algorithms; you can use it fr meshoptimizer is hosted on GitHub; you can download the latest release using git: ``` -git clone -b v0.20 https://github.com/zeux/meshoptimizer.git +git clone -b v0.21 https://github.com/zeux/meshoptimizer.git ``` -Alternatively you can [download the .zip archive from GitHub](https://github.com/zeux/meshoptimizer/archive/v0.20.zip). +Alternatively you can [download the .zip archive from GitHub](https://github.com/zeux/meshoptimizer/archive/v0.21.zip). The library is also available as a package ([ArchLinux](https://aur.archlinux.org/packages/meshoptimizer/), [Debian](https://packages.debian.org/libmeshoptimizer), [Ubuntu](https://packages.ubuntu.com/libmeshoptimizer), [Vcpkg](https://github.com/microsoft/vcpkg/tree/master/ports/meshoptimizer)). diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index 9633959112..2af672334f 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -1,5 +1,5 @@ /** - * gltfpack - version 0.20 + * gltfpack - version 0.21 * * Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at https://github.com/zeux/meshoptimizer diff --git a/gltf/package.json b/gltf/package.json index 962285a139..13cda90695 100644 --- a/gltf/package.json +++ b/gltf/package.json @@ -1,6 +1,6 @@ { "name": "gltfpack", - "version": "0.20.0", + "version": "0.21.0", "description": "A command-line tool that can optimize glTF files for size and speed", "author": "Arseny Kapoulkine", "license": "MIT", diff --git a/js/meshopt_decoder.js b/js/meshopt_decoder.js index 59d6ecd08b..0a53115141 100644 --- a/js/meshopt_decoder.js +++ b/js/meshopt_decoder.js @@ -3,7 +3,7 @@ var MeshoptDecoder = (function() { "use strict"; // Built with clang version 18.1.2 - // Built from meshoptimizer 0.20 + // Built from meshoptimizer 0.21 var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; diff --git a/js/meshopt_decoder.module.js b/js/meshopt_decoder.module.js index d5f36710a4..fd5631edaf 100644 --- a/js/meshopt_decoder.module.js +++ b/js/meshopt_decoder.module.js @@ -2,7 +2,7 @@ // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptDecoder = (function() { // Built with clang version 18.1.2 - // Built from meshoptimizer 0.20 + // Built from meshoptimizer 0.21 var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; diff --git a/js/meshopt_encoder.js b/js/meshopt_encoder.js index 7c0f8697db..e0931ea3e9 100644 --- a/js/meshopt_encoder.js +++ b/js/meshopt_encoder.js @@ -3,7 +3,7 @@ var MeshoptEncoder = (function() { "use strict"; // Built with clang version 18.1.2 - // Built from meshoptimizer 0.20 + // Built from meshoptimizer 0.21 var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_encoder.module.js b/js/meshopt_encoder.module.js index c2b7efd88d..b95c1b6d29 100644 --- a/js/meshopt_encoder.module.js +++ b/js/meshopt_encoder.module.js @@ -2,7 +2,7 @@ // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptEncoder = (function() { // Built with clang version 18.1.2 - // Built from meshoptimizer 0.20 + // Built from meshoptimizer 0.21 var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 73590683ac..97f17e55d7 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -3,8 +3,8 @@ var MeshoptSimplifier = (function() { "use strict"; // Built with clang version 18.1.2 - // Built from meshoptimizer 0.20 - var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;T9Vsdbk;v6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascxfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgHBdxasceBd2asaHBdlascuadcitadcFFFFe0Ecbyd;O1jjbHjjjjbbgOBdzascdBd2asaOBdwasclfaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd;O1jjbHjjjjbbgXBdCasciBd2asaCcbyd;O1jjbHjjjjbbgQBdKasclBd2alcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd;O1jjbHjjjjbbgLBd3ascvBd2aLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd;S1jjbH:bjjjbbasclBd2asalcbyd;O1jjbHjjjjbbg3Bd3ascvBd2asaCcbyd;O1jjbHjjjjbbgzBdaascoBd2asaCcbyd;O1jjbHjjjjbbgKBd8KascrBd2azcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkascualcx2alc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbg8KBdycwhAascwBd2a8Kaialavz:djjjbcbhvdnaDTmbcbh8EascuaDal2gzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgvBd8ScDhAascDBd2alTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascxfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd;O1jjbHjjjjbbgKBdbasaAcefg5Bd2aKcbazz:ljjjbh8FdndndnaDTmbascxfa5cdtfaLcbyd;O1jjbHjjjjbbgqBdbasaAcdVgKBd2aqcbazz:ljjjb8AascxfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd;O1jjbHjjjjbbgwBdbasaAcifBd2awcbaKz:ljjjb8AadmexdkcbhqcbhwadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Jaeh8Ainaea8Jcdtfh8EcbhKina3a8EaKcj1jjbfydbcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:q1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekdna8KaLcx2fgYIdwa8Ka5cx2fgAIdwg8P:tgIaINaYIdbaAIdbg8U:tgyayNaYIdlaAIdlg8S:tg8Ra8RNMM:rg8NJbbbb9ETmbaIa8N:vhIa8Ra8N:vh8Raya8N:vhykJbbacJbbacJbbjZazceSEaEceSEh8Xdna8Ka8EaKc:e1jjbfydbcdtfydbcx2fgzIdwa8P:tgRaIaRaINazIdba8U:tg8YayNa8RazIdla8S:tg8WNMMg8VN:tgRaRNa8Yaya8VN:tgIaINa8Wa8Ra8VN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNg8RaINNg8VazIdbMUdbazaya8RayNg8XNg8YazIdlMUdlazaRa8RaRNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIa8RaRa8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Jcifg8Jad6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tgRaRNaKIdlaLIdlg80:tg8Ra8RNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNaRazIdba8Z:tg8PNa8RazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNa8RaIN:ta8VNh83a8Ya8RNa8SaIN:ta8VNhUa8Xa8PNaRaIN:ta8VNh85a8YaRNa8PaIN:ta8VNh86aRa8SNa8Pa8RN:tgIaINa8Ra8NNa8SayN:tgIaINaya8PNa8NaRN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tg8RNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUa8RNa83a8PNMgRNUdbazaIa86a8RNa85a8PNMg8RNUdbazcxfaIa87ayNa88aRNa8Na89a8RNMMMg8NNUdbaIayaRNNa8YMh8YaIaya8RNNa8WMh8WaIaRa8RNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIaRa8NNNa8VMh8VaIa8Ra8NNNa8XMh8XaIayayNNa80Mh80aIaRaRNNa8:Mh8:aIa8Ra8RNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaqaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyawaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydlhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbh8Mascxfasyd2gzcdtfa8MBdbasazcefgKBd2ascxfaKcdtfcuamcdtamcFFFFi0Ecbyd;O1jjbHjjjjbbgeBdbasazcdfgKBd2ascxfaKcdtfaCcbyd;O1jjbHjjjjbbgOBdbasazcifgKBd2ascxfaKcdtfalcbyd;O1jjbHjjjjbbgcBdbasazclfBd2Jbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasclfabadgoalaXz:cjjjbabhAcbhdcbhginabagcdtfh8JcbhzindnaXaAazfydbgLcdtgYfydbg5aXa8Jazc:S1jjbfydbcdtfydbgKcdtfydbgESmba3aKfRbbg8Acv2a3aLfRbbg8Efc;a1jjbfRbbgia8Ecv2a8Afg8Lc;a1jjbfRbbgHVcFeGTmbdnaEa59nmba8Lc:q1jjbfRbbcFeGmekdna8Ea8A9hmba8EcufcFeGce0mbaaaYfydbaK9hmeka8Madcx2fg5aKaLaHcFeGgEEBdla5aLaKaEEBdba5aEaiGcb9hBdwadcefhdkazclfgzcx9hmbkdnagcifggao9pmbaAcxfhAadcifam9nmekkdnadmbaohdxikcbh8AinJbbbbJbbjZa8FaXa8Ma8Acx2fg5ydlgEa5ydbg8Ea5ydwgKEgAcdtfydbgic8S2gHfgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEgYcx2fgKIdwg8RNazIdzaKIdbg8NNazIdaMgIaIMMa8RNazIdlaKIdlg8PNazIdCa8RNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbggc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwgRNazIdzaKIdbg8UNazIdaMgIaIMMaRNazIdlaKIdlg8SNazIdCaRNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfh8Ja5clfh8LdnaDTmbaqaLfgLIdwaRNaLIdza8UNaLIdaMgIaIMMaRNaLIdla8SNaLIdCaRNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKawagaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaqaHfgLIdwa8RNaLIdza8NNaLIdaMgIaIMMa8RNaLIdla8PNaLIdCa8RNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMhRavaYaD2cdtfhKawaiaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNaRMMhRaKclfhKazczfhzaLcufgLmbka8XaR:lMh8Xa8Yay:lMh8Yka8LaEaYa8Ya8X9FgzEBdba5a8EaAazEBdba8Ja8Ya8XazEUdba8Acefg8Aad9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzadhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbaeaLcdtfazBdbaKcxfhKadazcefgz9hmbkaoak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydwh6cbhHcbh8Ldnina8Maea8Lcdtfydbcx2fg8JIdwgya8W9EmeaHa9e9pmeJFFuuhIdna9iad9pmba8Maea9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaHa9h0mdkdnaSaXa8Jydlg9kcdtg0fydbg5fg9mRbbaSaXa8JydbgAcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fgYcwfhgaYclfhCa8Ka9ocx2fgicwfhraiclfh9qcbhKceh8AdnindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbgR:tgIa9qIdbaLIdlg8R:tg8NNaiIdbaR:tg8PaEIdla8R:tgyN:taIaCIdba8R:tg8UNaYIdbaR:tg8SayN:tNayarIdbaLIdwg8R:tg8VNa8NaEIdwa8R:tgRN:tayagIdba8R:tg8RNa8UaRN:tNaRa8PNa8VaIN:taRa8SNa8RaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6h8Aa8EaK9hmbkka8AceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaqaLfgzaqaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2h8Aa9ca52hYawhKaDhEinaKaYfgzaKa8AfgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkka8JcwfhKdndndndna3aAfgLRbbc9:fPdebdkaAhzinaOazcdtgzfa5BdbaQazfydbgzaA9hmbxikkaQa0fydbhzaQa9nfydbhAaOa9nfa9kBdbazh9kkaOaAcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaHfhHka8Lcefg8Lad9hmbkkdnaTmbaohdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8Ecwfa5Bdba8EclfaLBdbadcifhdkazcxfhzaEcifgEao6mbkadak9nmdxbkkasclfabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd2gzcdtascxffc98fhXdninazTmeaXydbcbyd;S1jjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk:2ldouv998Jjjjjbca9RglcFFF;7rBd3al9cFFF;7;3FF:;Fb83dCalcFFF97Bdzal9cFFF;7FFF:;u83dwdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZJbbbbalIdwalIdCgk:tgqaqJbbbb9DEgqalIdxalIdKgx:tgmamaq9DEgqalIdzalId3gm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;0Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbgqBdxawceBd2aqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd;O1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;O1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;O1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;O1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;O1jjbHjjjjbbgeBdaawcoBd2awaicbyd;O1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;S1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; + // Built from meshoptimizer 0.21 + var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index 5b540a4a52..54785ca84a 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -2,8 +2,8 @@ // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) var MeshoptSimplifier = (function() { // Built with clang version 18.1.2 - // Built from meshoptimizer 0.20 - var wasm = "b9H79Tebbbe9Fk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gluuuub9Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdxmq;T9Vsdbk;v6iKuY99Hu8Jjjjjbc;W;ab9Rgs8Kjjjjbascxfcbc;Kbz:ljjjb8AascualcefgzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgHBdxasceBd2asaHBdlascuadcitadcFFFFe0Ecbyd;O1jjbHjjjjbbgOBdzascdBd2asaOBdwasclfaeadalcbz:cjjjbascualcdtgAalcFFFFi0EgCcbyd;O1jjbHjjjjbbgXBdCasciBd2asaCcbyd;O1jjbHjjjjbbgQBdKasclBd2alcd4alfhLcehKinaKgzcethKazaL6mbkcbhYascuazcdtgKazcFFFFi0Ecbyd;O1jjbHjjjjbbgLBd3ascvBd2aLcFeaKz:ljjjbh8AdnalTmbavcd4hEazcufh3inaiaYaE2cdtfg5ydlgzcH4az7c:F:b:DD2a5ydbgzcH4az7c;D;O:B8J27a5ydwgzcH4az7c:3F;N8N27hLcbhzdndnina8AaLa3GgLcdtfg8EydbgKcuSmeaiaKaE2cdtfa5cxz:ojjjbTmdazcefgzaLfhLaza39nmbxdkka8EaYBdbaYhKkaXaYcdtfaKBdbaYcefgYal9hmbkcbhzaQhKinaKazBdbaKclfhKalazcefgz9hmbkcbhzaXhKaQhLindnazaKydbg3SmbaLaQa3cdtfg3ydbBdba3azBdbkaKclfhKaLclfhLalazcefgz9hmbkkcbh8Fa8Acbyd;S1jjbH:bjjjbbasclBd2asalcbyd;O1jjbHjjjjbbg3Bd3ascvBd2asaCcbyd;O1jjbHjjjjbbgzBdaascoBd2asaCcbyd;O1jjbHjjjjbbgKBd8KascrBd2azcFeaAz:ljjjbhaaKcFeaAz:ljjjbhhdnalTmbaOcwfhgindnaHa8FgLcefg8Fcdtfydbg5aHaLcdtgzfydbgKSmba5aK9RhAaOaKcitfh8Jahazfh8KaaazfhYcbhEindndna8JaEcitfydbg8EaL9hmbaYaLBdba8KaLBdbxekdnaHa8Ecdtg8LfgzclfydbgKazydbgzSmbaOazcitg5fydbaLSmeaKaz9Rh8Mazcu7aKfh8Aaga5fhKcbhzina8AazSmeazcefhzaKydbh5aKcwfhKa5aL9hmbkaza8M6mekaha8LfgzaLa8EazydbcuSEBdbaYa8EaLaYydbcuSEBdbkaEcefgEaA9hmbkka8Fal9hmbkaXhKaQhLahh5aahEcbhzindndnazaKydbg8E9hmbdnaqTmbaqazfRbbTmba3azfcl86bbxdkdnazaLydbg8E9hmbaEydbh8Edna5ydbg8Acu9hmba8Ecu9hmba3azfcb86bbxika3azfhYdnaza8ASmbaza8ESmbaYce86bbxikaYcl86bbxdkdnazaQa8Ecdtg8Afydb9hmbdna5ydbgYcuSmbazaYSmbaEydbgAcuSmbazaASmbaha8Afydbg8JcuSmba8Ja8ESmbaaa8Afydbg8AcuSmba8Aa8ESmbdnaXaYcdtfydbaXa8Acdtfydb9hmbaXaAcdtfydbaXa8Jcdtfydb9hmba3azfcd86bbxlka3azfcl86bbxika3azfcl86bbxdka3azfcl86bbxeka3azfa3a8EfRbb86bbkaKclfhKaLclfhLa5clfh5aEclfhEalazcefgz9hmbkamceGTmba3hzalhKindnazRbbce9hmbazcl86bbkazcefhzaKcufgKmbkkascualcx2alc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbg8KBdycwhAascwBd2a8Kaialavz:djjjbcbhvdnaDTmbcbh8EascuaDal2gzcdtazcFFFFi0Ecbyd;O1jjbHjjjjbbgvBd8ScDhAascDBd2alTmbarcd4cdth8AaDcdthYavhEinaohzawhKaEhLaDh5inaLazIdbaKIdbNUdbazclfhzaKclfhKaLclfhLa5cufg5mbkaoa8AfhoaEaYfhEa8Ecefg8Eal9hmbkkascxfaAcdtfcualc8S2gzalc;D;O;f8U0EgLcbyd;O1jjbHjjjjbbgKBdbasaAcefg5Bd2aKcbazz:ljjjbh8FdndndnaDTmbascxfa5cdtfaLcbyd;O1jjbHjjjjbbgqBdbasaAcdVgKBd2aqcbazz:ljjjb8AascxfaKcdtfcuaDal2gzcltgKazcFFFFb0Ecbyd;O1jjbHjjjjbbgwBdbasaAcifBd2awcbaKz:ljjjb8AadmexdkcbhqcbhwadTmekcbhEaehKindna8KaKclfydbg8Ecx2fgzIdba8KaKydbg8Acx2fgLIdbg8N:tgya8KaKcwfydbgYcx2fg5IdlaLIdlg8P:tgINa5Idba8N:tg8RazIdla8P:tg8SN:tgRaRNa8Sa5IdwaLIdwg8U:tg8VNaIazIdwa8U:tg8SN:tgIaINa8Sa8RNa8VayN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa8Acdtfydbc8S2fgzaIa8R:rg8RaINNg8SazIdbMUdbazaya8RayNg8WNg8VazIdlMUdlazaRa8RaRNg8XNg8YazIdwMUdwaza8WaINg8WazIdxMUdxaza8XaINg8ZazIdzMUdzaza8XayNg8XazIdCMUdCazaIa8RaRa8UNaIa8NNa8PayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXa8Ecdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdya8FaXaYcdtfydbc8S2fgza8SazIdbMUdbaza8VazIdlMUdlaza8YazIdwMUdwaza8WazIdxMUdxaza8ZazIdzMUdzaza8XazIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdyaKcxfhKaEcifgEad6mbkcbh8Jaeh8Ainaea8Jcdtfh8EcbhKina3a8EaKcj1jjbfydbcdtfydbgLfRbbhzdndna3a8AaKfydbg5fRbbgEc99fcFeGcpe0mbazceSmbazcd9hmekdnaEcufcFeGce0mbaaa5cdtfydbaL9hmekdnazcufcFeGce0mbahaLcdtfydba59hmekdnaEcv2azfc:q1jjbfRbbTmbaXaLcdtfydbaXa5cdtfydb0mekdna8KaLcx2fgYIdwa8Ka5cx2fgAIdwg8P:tgIaINaYIdbaAIdbg8U:tgyayNaYIdlaAIdlg8S:tg8Ra8RNMM:rg8NJbbbb9ETmbaIa8N:vhIa8Ra8N:vh8Raya8N:vhykJbbacJbbacJbbjZazceSEaEceSEh8Xdna8Ka8EaKc:e1jjbfydbcdtfydbcx2fgzIdwa8P:tgRaIaRaINazIdba8U:tg8YayNa8RazIdla8S:tg8WNMMg8VN:tgRaRNa8Yaya8VN:tgIaINa8Wa8Ra8VN:tgyayNMM:rg8RJbbbb9ETmbaRa8R:vhRaya8R:vhyaIa8R:vhIka8FaXa5cdtfydbc8S2fgzaIa8Xa8NNg8RaINNg8VazIdbMUdbazaya8RayNg8XNg8YazIdlMUdlazaRa8RaRNg8NNg8WazIdwMUdwaza8XaINg8XazIdxMUdxaza8NaINg8ZazIdzMUdzaza8NayNg80azIdCMUdCazaIa8RaRa8PNaIa8UNa8SayNMM:mg8PNg8NNgIazIdKMUdKazaya8NNgyazId3MUd3azaRa8NNgRazIdaMUdaaza8Na8PNg8NazId8KMUd8Kaza8RazIdyMUdya8FaXaLcdtfydbc8S2fgza8VazIdbMUdbaza8YazIdlMUdlaza8WazIdwMUdwaza8XazIdxMUdxaza8ZazIdzMUdzaza80azIdCMUdCazaIazIdKMUdKazayazId3MUd3azaRazIdaMUdaaza8NazId8KMUd8Kaza8RazIdyMUdykaKclfgKcx9hmbka8Acxfh8Aa8Jcifg8Jad6mbkaDTmbcbh8AinJbbbbh8Ua8Kaea8AcdtfgzclfydbgYcx2fgKIdwa8KazydbgAcx2fgLIdwg8W:tgyayNaKIdbaLIdbg8Z:tgRaRNaKIdlaLIdlg80:tg8Ra8RNMMg8Xa8Kazcwfydbg8Jcx2fgzIdwa8W:tg8NNayaya8NNaRazIdba8Z:tg8PNa8RazIdla80:tg8SNMMgIN:tJbbbbJbbjZa8Xa8Na8NNa8Pa8PNa8Sa8SNMMg8YNaIaIN:tg8V:va8VJbbbb9BEg8VNh81a8YayNa8NaIN:ta8VNhBa8Xa8SNa8RaIN:ta8VNh83a8Ya8RNa8SaIN:ta8VNhUa8Xa8PNaRaIN:ta8VNh85a8YaRNa8PaIN:ta8VNh86aRa8SNa8Pa8RN:tgIaINa8Ra8NNa8SayN:tgIaINaya8PNa8NaRN:tgIaINMM:r:rhIavaAaD2cdtfhKava8JaD2cdtfhLavaYaD2cdtfh5a8W:mh87a80:mh88a8Z:mh89cbhEaDh8EJbbbbh8SJbbbbh8VJbbbbh8XJbbbbh8YJbbbbh8WJbbbbh8ZJbbbbh80Jbbbbh8:JbbbbhZinasc;WbfaEfgzcwfaIaBa5IdbaKIdbg8N:tg8RNa81aLIdba8N:tg8PNMgyNUdbazclfaIaUa8RNa83a8PNMgRNUdbazaIa86a8RNa85a8PNMg8RNUdbazcxfaIa87ayNa88aRNa8Na89a8RNMMMg8NNUdbaIayaRNNa8YMh8YaIaya8RNNa8WMh8WaIaRa8RNNa8ZMh8ZaIa8Na8NNNa8UMh8UaIaya8NNNa8SMh8SaIaRa8NNNa8VMh8VaIa8Ra8NNNa8XMh8XaIayayNNa80Mh80aIaRaRNNa8:Mh8:aIa8Ra8RNNaZMhZaKclfhKa5clfh5aLclfhLaEczfhEa8Ecufg8EmbkaqaXaAcdtfydbgKc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXaYcdtfydbgYc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyaqaXa8JcdtfydbgAc8S2fgzaZazIdbMUdbaza8:azIdlMUdlaza80azIdwMUdwaza8ZazIdxMUdxaza8WazIdzMUdzaza8YazIdCMUdCaza8XazIdKMUdKaza8VazId3MUd3aza8SazIdaMUdaaza8UazId8KMUd8KazaIazIdyMUdyawaKaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaYaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbkawaAaD2cltfh8EcbhKaDh5ina8EaKfgzasc;WbfaKfgLIdbazIdbMUdbazclfgEaLclfIdbaEIdbMUdbazcwfgEaLcwfIdbaEIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKa5cufg5mbka8Acifg8Aad6mbkkdnabaeSmbabaeadcdtz:kjjjb8AkasydlhncbhzdnalTmbanclfhzanydbh5a3hKalhEcbhLincbazydbg8Ea59RaKRbbcpeGEaLfhLaKcefhKazclfhza8Eh5aEcufgEmbkaLce4hzkcuadaz9Rcifgmcx2amc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbh8Mascxfasyd2gzcdtfa8MBdbasazcefgKBd2ascxfaKcdtfcuamcdtamcFFFFi0Ecbyd;O1jjbHjjjjbbgeBdbasazcdfgKBd2ascxfaKcdtfaCcbyd;O1jjbHjjjjbbgOBdbasazcifgKBd2ascxfaKcdtfalcbyd;O1jjbHjjjjbbgcBdbasazclfBd2Jbbbbh8Zdnadak9nmbdnamci6mbaxaxNh8WaDclth9ca8McwfhJJbbbbh8ZinasclfabadgoalaXz:cjjjbabhAcbhdcbhginabagcdtfh8JcbhzindnaXaAazfydbgLcdtgYfydbg5aXa8Jazc:S1jjbfydbcdtfydbgKcdtfydbgESmba3aKfRbbg8Acv2a3aLfRbbg8Efc;a1jjbfRbbgia8Ecv2a8Afg8Lc;a1jjbfRbbgHVcFeGTmbdnaEa59nmba8Lc:q1jjbfRbbcFeGmekdna8Ea8A9hmba8EcufcFeGce0mbaaaYfydbaK9hmeka8Madcx2fg5aKaLaHcFeGgEEBdla5aLaKaEEBdba5aEaiGcb9hBdwadcefhdkazclfgzcx9hmbkdnagcifggao9pmbaAcxfhAadcifam9nmekkdnadmbaohdxikcbh8AinJbbbbJbbjZa8FaXa8Ma8Acx2fg5ydlgEa5ydbg8Ea5ydwgKEgAcdtfydbgic8S2gHfgzIdygI:vaIJbbbb9BEazIdwa8Ka8EaEaKEgYcx2fgKIdwg8RNazIdzaKIdbg8NNazIdaMgIaIMMa8RNazIdlaKIdlg8PNazIdCa8RNazId3MgIaIMMa8PNazIdba8NNazIdxa8PNazIdKMgIaIMMa8NNazId8KMMM:lNh8XJbbbbJbbjZa8FaXa8Ecdtfydbggc8S2gLfgzIdygI:vaIJbbbb9BEazIdwa8KaEcx2fgKIdwgRNazIdzaKIdbg8UNazIdaMgIaIMMaRNazIdlaKIdlg8SNazIdCaRNazId3MgIaIMMa8SNazIdba8UNazIdxa8SNazIdKMgIaIMMa8UNazId8KMMM:lNh8Ya5cwfh8Ja5clfh8LdnaDTmbaqaLfgLIdwaRNaLIdza8UNaLIdaMgIaIMMaRNaLIdla8SNaLIdCaRNaLId3MgIaIMMa8SNaLIdba8UNaLIdxa8SNaLIdKMgIaIMMa8UNaLId8KMMMhyavaEaD2cdtfhKawagaD2cltfhzaLIdyh8VaDhLinaKIdbgIJbbb;aNazcxfIdbaRazcwfIdbNa8UazIdbNa8SazclfIdbNMMMNaIaINa8VNayMMhyaKclfhKazczfhzaLcufgLmbkaqaHfgLIdwa8RNaLIdza8NNaLIdaMgIaIMMa8RNaLIdla8PNaLIdCa8RNaLId3MgIaIMMa8PNaLIdba8NNaLIdxa8PNaLIdKMgIaIMMa8NNaLId8KMMMhRavaYaD2cdtfhKawaiaD2cltfhzaLIdyh8UaDhLinaKIdbgIJbbb;aNazcxfIdba8RazcwfIdbNa8NazIdbNa8PazclfIdbNMMMNaIaINa8UNaRMMhRaKclfhKazczfhzaLcufgLmbka8XaR:lMh8Xa8Yay:lMh8Yka8LaEaYa8Ya8X9FgzEBdba5a8EaAazEBdba8Ja8Ya8XazEUdba8Acefg8Aad9hmbkasc;Wbfcbcj;abz:ljjjb8AaJhzadhKinasc;WbfazydbcO4c;8ZGfgLaLydbcefBdbazcxfhzaKcufgKmbkcbhzcbhKinasc;WbfazfgLydbh5aLaKBdba5aKfhKazclfgzcj;ab9hmbkcbhzaJhKinasc;WbfaKydbcO4c;8ZGfgLaLydbgLcefBdbaeaLcdtfazBdbaKcxfhKadazcefgz9hmbkaoak9RgLci9Uh9ednalTmbcbhzaOhKinaKazBdbaKclfhKalazcefgz9hmbkkcbhTaccbalz:ljjjbhSaLcO9Uh9ha9ece4h9iasydwh6cbhHcbh8Ldnina8Maea8Lcdtfydbcx2fg8JIdwgya8W9EmeaHa9e9pmeJFFuuhIdna9iad9pmba8Maea9icdtfydbcx2fIdwJbb;aZNhIkdnayaI9ETmbaHa9h0mdkdnaSaXa8Jydlg9kcdtg0fydbg5fg9mRbbaSaXa8JydbgAcdtg9nfydbg9ofg9pRbbVmbdnana9ocdtfgzclfydbgKazydbgzSmbaKaz9Rh8Ea6azcitfhza8Ka5cx2fgYcwfhgaYclfhCa8Ka9ocx2fgicwfhraiclfh9qcbhKceh8AdnindnaOazydbcdtfydbgLa5SmbaOazclfydbcdtfydbgEa5SmbaLaESmba8KaEcx2fgEIdba8KaLcx2fgLIdbgR:tgIa9qIdbaLIdlg8R:tg8NNaiIdbaR:tg8PaEIdla8R:tgyN:taIaCIdba8R:tg8UNaYIdbaR:tg8SayN:tNayarIdbaLIdwg8R:tg8VNa8NaEIdwa8R:tgRN:tayagIdba8R:tg8RNa8UaRN:tNaRa8PNa8VaIN:taRa8SNa8RaIN:tNMMJbbbb9FmdkazcwfhzaKcefgKa8E6h8Aa8EaK9hmbkka8AceGTmba9icefh9ixeka8Fa5c8S2gLfgza8Fa9oc8S2gEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdydnaDTmbaqaLfgzaqaEfgKIdbazIdbMUdbazaKIdlazIdlMUdlazaKIdwazIdwMUdwazaKIdxazIdxMUdxazaKIdzazIdzMUdzazaKIdCazIdCMUdCazaKIdKazIdKMUdKazaKId3azId3MUd3azaKIdaazIdaMUdaazaKId8KazId8KMUd8KazaKIdyazIdyMUdya9ca9o2h8Aa9ca52hYawhKaDhEinaKaYfgzaKa8AfgLIdbazIdbMUdbazclfg8EaLclfIdba8EIdbMUdbazcwfg8EaLcwfIdba8EIdbMUdbazcxfgzaLcxfIdbazIdbMUdbaKczfhKaEcufgEmbkka8JcwfhKdndndndna3aAfgLRbbc9:fPdebdkaAhzinaOazcdtgzfa5BdbaQazfydbgzaA9hmbxikkaQa0fydbhzaQa9nfydbhAaOa9nfa9kBdbazh9kkaOaAcdtfa9kBdbka9pce86bba9mce86bbaKIdbgIa8Za8ZaI9DEh8ZaTcefhTcecdaLRbbceSEaHfhHka8Lcefg8Lad9hmbkkdnaTmbaohdxikdnalTmbcbhKaahzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaaa5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkcbhKahhzindnazydbgLcuSmbdnaKaOaLcdtg5fydbgL9hmbaha5fydbhLkazaLBdbkazclfhzalaKcefgK9hmbkkcbhdabhzcbhEindnaOazydbcdtfydbgKaOazclfydbcdtfydbgLSmbaKaOazcwfydbcdtfydbg5SmbaLa5Smbabadcdtfg8EaKBdba8Ecwfa5Bdba8EclfaLBdbadcifhdkazcxfhzaEcifgEao6mbkadak9nmdxbkkasclfabadalaXz:cjjjbkdnaPTmbaPa8Z:rUdbkasyd2gzcdtascxffc98fhXdninazTmeaXydbcbyd;S1jjbH:bjjjbbaXc98fhXazcufhzxbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk:2ldouv998Jjjjjbca9RglcFFF;7rBd3al9cFFF;7;3FF:;Fb83dCalcFFF97Bdzal9cFFF;7FFF:;u83dwdnadTmbaicd4hvdnabTmbavcdthocbhraehwinabarcx2fgiaearav2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinalcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawaofhwarcefgrad9hmbxdkkavcdthrcbhwincbhiinalcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbalcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbkkdnabTmbadTmbJbbbbJbbjZJbbbbalIdwalIdCgk:tgqaqJbbbb9DEgqalIdxalIdKgx:tgmamaq9DEgqalIdzalId3gm:tgPaPaq9DEgq:vaqJbbbb9BEhqinabaqabIdbak:tNUdbabclfgiaqaiIdbax:tNUdbabcwfgiaqaiIdbam:tNUdbabcxfhbadcufgdmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;0Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;O1jjbHjjjjbbgqBdxawceBd2aqaeadaiz:djjjbawcuadcdtadcFFFFi0Egkcbyd;O1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;O1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;O1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;O1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;O1jjbHjjjjbbgeBdaawcoBd2awaicbyd;O1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;S1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; + // Built from meshoptimizer 0.21 + var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/package.json b/js/package.json index 3b355ca287..f06429a144 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "meshoptimizer", - "version": "0.20.0", + "version": "0.21.0", "description": "Mesh optimizaiton library that makes meshes smaller and faster to render", "author": "Arseny Kapoulkine", "license": "MIT", diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index c6a1367b44..6c8dcd7e86 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -1,5 +1,5 @@ /** - * meshoptimizer - version 0.20 + * meshoptimizer - version 0.21 * * Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at https://github.com/zeux/meshoptimizer @@ -12,7 +12,7 @@ #include /* Version macro; major * 1000 + minor * 10 + patch */ -#define MESHOPTIMIZER_VERSION 200 /* 0.20 */ +#define MESHOPTIMIZER_VERSION 210 /* 0.21 */ /* If no API is defined, assume default */ #ifndef MESHOPTIMIZER_API From 47aafa533b439a78b53cd2854c177db61be7e666 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 25 Jun 2024 10:16:03 -0700 Subject: [PATCH 134/581] js: Adjust simplify/simplifyWithAttributes assertions To make ErrorAbsolute mode useful in JS, it needs to allow values outside of 0..1 range; for simplicity we just remove the upper bound for now. Also, previously flags could contain values that are not recognized as valid options and this would silently work; these are now checked with assertions to prevent mistakes. --- js/meshopt_simplifier.js | 6 ++++-- js/meshopt_simplifier.module.js | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 97f17e55d7..77e09e5666 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -183,10 +183,11 @@ var MeshoptSimplifier = (function() { assert(vertex_positions_stride >= 3); assert(target_index_count >= 0 && target_index_count <= indices.length); assert(target_index_count % 3 == 0); - assert(target_error >= 0 && target_error <= 1); + assert(target_error >= 0); var options = 0; for (var i = 0; i < (flags ? flags.length : 0); ++i) { + assert(flags[i] in simplifyOptions); options |= simplifyOptions[flags[i]]; } @@ -210,13 +211,14 @@ var MeshoptSimplifier = (function() { assert(vertex_lock == null || vertex_lock.length == vertex_positions.length); assert(target_index_count >= 0 && target_index_count <= indices.length); assert(target_index_count % 3 == 0); - assert(target_error >= 0 && target_error <= 1); + assert(target_error >= 0); assert(Array.isArray(attribute_weights)); assert(vertex_attributes_stride >= attribute_weights.length); assert(attribute_weights.length <= 16); var options = 0; for (var i = 0; i < (flags ? flags.length : 0); ++i) { + assert(flags[i] in simplifyOptions); options |= simplifyOptions[flags[i]]; } diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index 54785ca84a..5d4cd66524 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -182,10 +182,11 @@ var MeshoptSimplifier = (function() { assert(vertex_positions_stride >= 3); assert(target_index_count >= 0 && target_index_count <= indices.length); assert(target_index_count % 3 == 0); - assert(target_error >= 0 && target_error <= 1); + assert(target_error >= 0); var options = 0; for (var i = 0; i < (flags ? flags.length : 0); ++i) { + assert(flags[i] in simplifyOptions); options |= simplifyOptions[flags[i]]; } @@ -209,13 +210,14 @@ var MeshoptSimplifier = (function() { assert(vertex_lock == null || vertex_lock.length == vertex_positions.length); assert(target_index_count >= 0 && target_index_count <= indices.length); assert(target_index_count % 3 == 0); - assert(target_error >= 0 && target_error <= 1); + assert(target_error >= 0); assert(Array.isArray(attribute_weights)); assert(vertex_attributes_stride >= attribute_weights.length); assert(attribute_weights.length <= 16); var options = 0; for (var i = 0; i < (flags ? flags.length : 0); ++i) { + assert(flags[i] in simplifyOptions); options |= simplifyOptions[flags[i]]; } From 9214ca8a9ad703d204ab7376fe40fef8065ae492 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 29 Jun 2024 10:59:57 -0700 Subject: [PATCH 135/581] Allow overriding MESHOPTIMIZER_EXPERIMENTAL externally Similarly to MESHOPTIMIZER_API, we now define MESHOPTIMIZER_EXPERIMENTAL only if an existing definition is absent. This allows, for example, setting this to a deprecated attribute which still compiles the library itself cleanly, but will warn for any use of experimental APIs for dependent code. Another interesting use case is building .so where the experimental symbols are not exported, which usually results in an ABI stable interface. --- src/meshoptimizer.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index 6c8dcd7e86..cb3745a2cc 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -29,7 +29,9 @@ #endif /* Experimental APIs have unstable interface and might have implementation that's not fully tested or optimized */ +#ifndef MESHOPTIMIZER_EXPERIMENTAL #define MESHOPTIMIZER_EXPERIMENTAL MESHOPTIMIZER_API +#endif /* C interface */ #ifdef __cplusplus From 54511f2dd7a0f6259520a279c3d8d05f86e9418e Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 1 Jul 2024 12:48:54 -0700 Subject: [PATCH 136/581] js: Change TypeScript sources to use tabs for consistency This matches most JS source in this repository. --- js/meshopt_decoder.module.d.ts | 18 +++++++++--------- js/meshopt_encoder.module.d.ts | 24 ++++++++++++------------ js/meshopt_simplifier.module.d.ts | 20 ++++++++++---------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/js/meshopt_decoder.module.d.ts b/js/meshopt_decoder.module.d.ts index 8546a2f41a..667dfb7be4 100644 --- a/js/meshopt_decoder.module.d.ts +++ b/js/meshopt_decoder.module.d.ts @@ -1,15 +1,15 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) export const MeshoptDecoder: { - supported: boolean; - ready: Promise; - - decodeVertexBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array, filter?: string) => void; - decodeIndexBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array) => void; - decodeIndexSequence: (target: Uint8Array, count: number, size: number, source: Uint8Array) => void; + supported: boolean; + ready: Promise; - decodeGltfBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array, mode: string, filter?: string) => void; + decodeVertexBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array, filter?: string) => void; + decodeIndexBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array) => void; + decodeIndexSequence: (target: Uint8Array, count: number, size: number, source: Uint8Array) => void; - useWorkers: (count: number) => void; - decodeGltfBufferAsync: (count: number, size: number, source: Uint8Array, mode: string, filter?: string) => Promise; + decodeGltfBuffer: (target: Uint8Array, count: number, size: number, source: Uint8Array, mode: string, filter?: string) => void; + + useWorkers: (count: number) => void; + decodeGltfBufferAsync: (count: number, size: number, source: Uint8Array, mode: string, filter?: string) => Promise; }; diff --git a/js/meshopt_encoder.module.d.ts b/js/meshopt_encoder.module.d.ts index 4855326aff..49000dfcff 100644 --- a/js/meshopt_encoder.module.d.ts +++ b/js/meshopt_encoder.module.d.ts @@ -1,19 +1,19 @@ // This file is part of meshoptimizer library and is distributed under the terms of MIT License. // Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) export const MeshoptEncoder: { - supported: boolean; - ready: Promise; + supported: boolean; + ready: Promise; - reorderMesh: (indices: Uint32Array, triangles: boolean, optsize: boolean) => [Uint32Array, number]; - reorderPoints: (positions: Float32Array, positions_stride: number) => Uint32Array; - - encodeVertexBuffer: (source: Uint8Array, count: number, size: number) => Uint8Array; - encodeIndexBuffer: (source: Uint8Array, count: number, size: number) => Uint8Array; - encodeIndexSequence: (source: Uint8Array, count: number, size: number) => Uint8Array; + reorderMesh: (indices: Uint32Array, triangles: boolean, optsize: boolean) => [Uint32Array, number]; + reorderPoints: (positions: Float32Array, positions_stride: number) => Uint32Array; - encodeGltfBuffer: (source: Uint8Array, count: number, size: number, mode: string) => Uint8Array; + encodeVertexBuffer: (source: Uint8Array, count: number, size: number) => Uint8Array; + encodeIndexBuffer: (source: Uint8Array, count: number, size: number) => Uint8Array; + encodeIndexSequence: (source: Uint8Array, count: number, size: number) => Uint8Array; - encodeFilterOct: (source: Float32Array, count: number, stride: number, bits: number) => Uint8Array; - encodeFilterQuat: (source: Float32Array, count: number, stride: number, bits: number) => Uint8Array; - encodeFilterExp: (source: Float32Array, count: number, stride: number, bits: number, mode?: "Separate" | "SharedVector" | "SharedComponent") => Uint8Array; + encodeGltfBuffer: (source: Uint8Array, count: number, size: number, mode: string) => Uint8Array; + + encodeFilterOct: (source: Float32Array, count: number, stride: number, bits: number) => Uint8Array; + encodeFilterQuat: (source: Float32Array, count: number, stride: number, bits: number) => Uint8Array; + encodeFilterExp: (source: Float32Array, count: number, stride: number, bits: number, mode?: "Separate" | "SharedVector" | "SharedComponent") => Uint8Array; }; diff --git a/js/meshopt_simplifier.module.d.ts b/js/meshopt_simplifier.module.d.ts index b0131756b6..b2c042170f 100644 --- a/js/meshopt_simplifier.module.d.ts +++ b/js/meshopt_simplifier.module.d.ts @@ -3,20 +3,20 @@ export type Flags = "LockBorder" | "Sparse" | "ErrorAbsolute"; export const MeshoptSimplifier: { - supported: boolean; - ready: Promise; + supported: boolean; + ready: Promise; - useExperimentalFeatures: boolean; + useExperimentalFeatures: boolean; - compactMesh: (indices: Uint32Array) => [Uint32Array, number]; + compactMesh: (indices: Uint32Array) => [Uint32Array, number]; - simplify: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; + simplify: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; - // Experimental; requires useExperimentalFeatures to be set to true - simplifyWithAttributes: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, vertex_attributes: Float32Array, vertex_attributes_stride: number, attribute_weights: number[], vertex_lock: boolean[] | null, target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; + // Experimental; requires useExperimentalFeatures to be set to true + simplifyWithAttributes: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, vertex_attributes: Float32Array, vertex_attributes_stride: number, attribute_weights: number[], vertex_lock: boolean[] | null, target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number]; - getScale: (vertex_positions: Float32Array, vertex_positions_stride: number) => number; + getScale: (vertex_positions: Float32Array, vertex_positions_stride: number) => number; - // Experimental; requires useExperimentalFeatures to be set to true - simplifyPoints: (vertex_positions: Float32Array, vertex_positions_stride: number, target_vertex_count: number, vertex_colors?: Float32Array, vertex_colors_stride?: number, color_weight?: number) => Uint32Array; + // Experimental; requires useExperimentalFeatures to be set to true + simplifyPoints: (vertex_positions: Float32Array, vertex_positions_stride: number, target_vertex_count: number, vertex_colors?: Float32Array, vertex_colors_stride?: number, color_weight?: number) => Uint32Array; }; From be2de223f5d264da0278ea0fe71a35324f794312 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 1 Jul 2024 12:49:47 -0700 Subject: [PATCH 137/581] js: Change reference decoder to use tabs instead of spaces This matches all other JS sources in this folder. --- js/meshopt_decoder_reference.js | 624 ++++++++++++++++---------------- 1 file changed, 312 insertions(+), 312 deletions(-) diff --git a/js/meshopt_decoder_reference.js b/js/meshopt_decoder_reference.js index cc07de0e1b..cbf04e8a1b 100644 --- a/js/meshopt_decoder_reference.js +++ b/js/meshopt_decoder_reference.js @@ -10,336 +10,336 @@ MeshoptDecoder.supported = true; MeshoptDecoder.ready = Promise.resolve(); function assert(cond) { - if (!cond) { - throw new Error("Assertion failed"); - } + if (!cond) { + throw new Error("Assertion failed"); + } } function dezig(v) { - return ((v & 1) !== 0) ? ~(v >>> 1) : v >>> 1; + return ((v & 1) !== 0) ? ~(v >>> 1) : v >>> 1; } MeshoptDecoder.decodeVertexBuffer = (target, elementCount, byteStride, source, filter) => { - assert(source[0] === 0xA0); - - const maxBlockElements = Math.min((0x2000 / byteStride) & ~0x000F, 0x100); - - const deltas = new Uint8Array(0x10); - - const tailDataOffs = source.length - byteStride; - - // What deltas are stored relative to - const tempData = source.slice(tailDataOffs, tailDataOffs + byteStride); - - let srcOffs = 0x01; - - // Attribute Blocks - for (let dstElemBase = 0; dstElemBase < elementCount; dstElemBase += maxBlockElements) { - const attrBlockElementCount = Math.min(elementCount - dstElemBase, maxBlockElements); - const groupCount = ((attrBlockElementCount + 0x0F) & ~0x0F) >>> 4; - const headerByteCount = ((groupCount + 0x03) & ~0x03) >>> 2; - - // Data blocks - for (let byte = 0; byte < byteStride; byte++) { - let headerBitsOffs = srcOffs; - - srcOffs += headerByteCount; - for (let group = 0; group < groupCount; group++) { - const mode = (source[headerBitsOffs] >>> ((group & 0x03) << 1)) & 0x03; - // If this is the last group, move to the next byte of header bits. - if ((group & 0x03) === 0x03) - headerBitsOffs++; - - const dstElemGroup = dstElemBase + (group << 4); - - if (mode === 0) { - // bits 0: All 16 byte deltas are 0; the size of the encoded block is 0 bytes - deltas.fill(0x00); - } else if (mode === 1) { - // bits 1: Deltas are using 2-bit sentinel encoding; the size of the encoded block is [4..20] bytes - const srcBase = srcOffs; - srcOffs += 0x04; - for (let m = 0; m < 0x10; m++) { - // 0 = >>> 6, 1 = >>> 4, 2 = >>> 2, 3 = >>> 0 - const shift = (6 - ((m & 0x03) << 1)); - let delta = (source[srcBase + (m >>> 2)] >>> shift) & 0x03; - if (delta === 3) - delta = source[srcOffs++]; - deltas[m] = delta; - } - } else if (mode === 2) { - // bits 2: Deltas are using 4-bit sentinel encoding; the size of the encoded block is [8..24] bytes - const srcBase = srcOffs; - srcOffs += 0x08; - for (let m = 0; m < 0x10; m++) { - // 0 = >>> 6, 1 = >>> 4, 2 = >>> 2, 3 = >>> 0 - const shift = (m & 0x01) ? 0 : 4; - let delta = (source[srcBase + (m >>> 1)] >>> shift) & 0x0f; - if (delta === 0xf) - delta = source[srcOffs++]; - deltas[m] = delta; - } - } else { - // bits 3: All 16 byte deltas are stored verbatim; the size of the encoded block is 16 bytes - deltas.set(source.subarray(srcOffs, srcOffs + 0x10)); - srcOffs += 0x10; - } - - // Go through and apply deltas to data - for (let m = 0; m < 0x10; m++) { - const dstElem = dstElemGroup + m; - if (dstElem >= elementCount) - break; - - const delta = dezig(deltas[m]); - const dstOffs = dstElem * byteStride + byte; - target[dstOffs] = (tempData[byte] += delta); - } - } - } - } - - // Filters - only applied if filter isn't undefined or NONE - if (filter === 'OCTAHEDRAL') { - assert(byteStride === 4 || byteStride === 8); - - let dst, maxInt; - if (byteStride === 4) { - dst = new Int8Array(target.buffer); - maxInt = 127; - } else { - dst = new Int16Array(target.buffer); - maxInt = 32767; - } - - for (let i = 0; i < 4 * elementCount; i += 4) { - let x = dst[i + 0], y = dst[i + 1], one = dst[i + 2]; - x /= one; - y /= one; - const z = 1.0 - Math.abs(x) - Math.abs(y); - const t = Math.max(-z, 0.0); - x -= (x >= 0) ? t : -t; - y -= (y >= 0) ? t : -t; - const h = maxInt / Math.hypot(x, y, z); - dst[i + 0] = Math.round(x * h); - dst[i + 1] = Math.round(y * h); - dst[i + 2] = Math.round(z * h); - // keep dst[i + 3] as is - } - } else if (filter === 'QUATERNION') { - assert(byteStride === 8); - - const dst = new Int16Array(target.buffer); - - for (let i = 0; i < 4 * elementCount; i += 4) { - const inputW = dst[i + 3]; - const maxComponent = inputW & 0x03; - const s = Math.SQRT1_2 / (inputW | 0x03); - let x = dst[i + 0] * s; - let y = dst[i + 1] * s; - let z = dst[i + 2] * s; - let w = Math.sqrt(Math.max(0.0, 1.0 - x**2 - y**2 - z**2)); - dst[i + (maxComponent + 1) % 4] = Math.round(x * 32767); - dst[i + (maxComponent + 2) % 4] = Math.round(y * 32767); - dst[i + (maxComponent + 3) % 4] = Math.round(z * 32767); - dst[i + (maxComponent + 0) % 4] = Math.round(w * 32767); - } - } else if (filter === 'EXPONENTIAL') { - assert((byteStride & 0x03) === 0x00); - - const src = new Int32Array(target.buffer); - const dst = new Float32Array(target.buffer); - for (let i = 0; i < (byteStride * elementCount) / 4; i++) { - const v = src[i], exp = v >> 24, mantissa = (v << 8) >> 8; - dst[i] = 2.0**exp * mantissa; - } - } + assert(source[0] === 0xA0); + + const maxBlockElements = Math.min((0x2000 / byteStride) & ~0x000F, 0x100); + + const deltas = new Uint8Array(0x10); + + const tailDataOffs = source.length - byteStride; + + // What deltas are stored relative to + const tempData = source.slice(tailDataOffs, tailDataOffs + byteStride); + + let srcOffs = 0x01; + + // Attribute Blocks + for (let dstElemBase = 0; dstElemBase < elementCount; dstElemBase += maxBlockElements) { + const attrBlockElementCount = Math.min(elementCount - dstElemBase, maxBlockElements); + const groupCount = ((attrBlockElementCount + 0x0F) & ~0x0F) >>> 4; + const headerByteCount = ((groupCount + 0x03) & ~0x03) >>> 2; + + // Data blocks + for (let byte = 0; byte < byteStride; byte++) { + let headerBitsOffs = srcOffs; + + srcOffs += headerByteCount; + for (let group = 0; group < groupCount; group++) { + const mode = (source[headerBitsOffs] >>> ((group & 0x03) << 1)) & 0x03; + // If this is the last group, move to the next byte of header bits. + if ((group & 0x03) === 0x03) + headerBitsOffs++; + + const dstElemGroup = dstElemBase + (group << 4); + + if (mode === 0) { + // bits 0: All 16 byte deltas are 0; the size of the encoded block is 0 bytes + deltas.fill(0x00); + } else if (mode === 1) { + // bits 1: Deltas are using 2-bit sentinel encoding; the size of the encoded block is [4..20] bytes + const srcBase = srcOffs; + srcOffs += 0x04; + for (let m = 0; m < 0x10; m++) { + // 0 = >>> 6, 1 = >>> 4, 2 = >>> 2, 3 = >>> 0 + const shift = (6 - ((m & 0x03) << 1)); + let delta = (source[srcBase + (m >>> 2)] >>> shift) & 0x03; + if (delta === 3) + delta = source[srcOffs++]; + deltas[m] = delta; + } + } else if (mode === 2) { + // bits 2: Deltas are using 4-bit sentinel encoding; the size of the encoded block is [8..24] bytes + const srcBase = srcOffs; + srcOffs += 0x08; + for (let m = 0; m < 0x10; m++) { + // 0 = >>> 6, 1 = >>> 4, 2 = >>> 2, 3 = >>> 0 + const shift = (m & 0x01) ? 0 : 4; + let delta = (source[srcBase + (m >>> 1)] >>> shift) & 0x0f; + if (delta === 0xf) + delta = source[srcOffs++]; + deltas[m] = delta; + } + } else { + // bits 3: All 16 byte deltas are stored verbatim; the size of the encoded block is 16 bytes + deltas.set(source.subarray(srcOffs, srcOffs + 0x10)); + srcOffs += 0x10; + } + + // Go through and apply deltas to data + for (let m = 0; m < 0x10; m++) { + const dstElem = dstElemGroup + m; + if (dstElem >= elementCount) + break; + + const delta = dezig(deltas[m]); + const dstOffs = dstElem * byteStride + byte; + target[dstOffs] = (tempData[byte] += delta); + } + } + } + } + + // Filters - only applied if filter isn't undefined or NONE + if (filter === 'OCTAHEDRAL') { + assert(byteStride === 4 || byteStride === 8); + + let dst, maxInt; + if (byteStride === 4) { + dst = new Int8Array(target.buffer); + maxInt = 127; + } else { + dst = new Int16Array(target.buffer); + maxInt = 32767; + } + + for (let i = 0; i < 4 * elementCount; i += 4) { + let x = dst[i + 0], y = dst[i + 1], one = dst[i + 2]; + x /= one; + y /= one; + const z = 1.0 - Math.abs(x) - Math.abs(y); + const t = Math.max(-z, 0.0); + x -= (x >= 0) ? t : -t; + y -= (y >= 0) ? t : -t; + const h = maxInt / Math.hypot(x, y, z); + dst[i + 0] = Math.round(x * h); + dst[i + 1] = Math.round(y * h); + dst[i + 2] = Math.round(z * h); + // keep dst[i + 3] as is + } + } else if (filter === 'QUATERNION') { + assert(byteStride === 8); + + const dst = new Int16Array(target.buffer); + + for (let i = 0; i < 4 * elementCount; i += 4) { + const inputW = dst[i + 3]; + const maxComponent = inputW & 0x03; + const s = Math.SQRT1_2 / (inputW | 0x03); + let x = dst[i + 0] * s; + let y = dst[i + 1] * s; + let z = dst[i + 2] * s; + let w = Math.sqrt(Math.max(0.0, 1.0 - x**2 - y**2 - z**2)); + dst[i + (maxComponent + 1) % 4] = Math.round(x * 32767); + dst[i + (maxComponent + 2) % 4] = Math.round(y * 32767); + dst[i + (maxComponent + 3) % 4] = Math.round(z * 32767); + dst[i + (maxComponent + 0) % 4] = Math.round(w * 32767); + } + } else if (filter === 'EXPONENTIAL') { + assert((byteStride & 0x03) === 0x00); + + const src = new Int32Array(target.buffer); + const dst = new Float32Array(target.buffer); + for (let i = 0; i < (byteStride * elementCount) / 4; i++) { + const v = src[i], exp = v >> 24, mantissa = (v << 8) >> 8; + dst[i] = 2.0**exp * mantissa; + } + } }; function pushfifo(fifo, n) { - for (let i = fifo.length - 1; i > 0; i--) - fifo[i] = fifo[i - 1]; - fifo[0] = n; + for (let i = fifo.length - 1; i > 0; i--) + fifo[i] = fifo[i - 1]; + fifo[0] = n; } MeshoptDecoder.decodeIndexBuffer = (target, count, byteStride, source) => { - assert(source[0] === 0xE1); - assert(count % 3 === 0); - assert(byteStride === 2 || byteStride === 4); - - let dst; - if (byteStride === 2) - dst = new Uint16Array(target.buffer); - else - dst = new Uint32Array(target.buffer); - - const triCount = count / 3; - - let codeOffs = 0x01; - let dataOffs = codeOffs + triCount; - let codeauxOffs = source.length - 0x10; - - function readLEB128() { - let n = 0; - for (let i = 0; ; i += 7) { - const b = source[dataOffs++]; - n |= (b & 0x7F) << i; - - if (b < 0x80) - return n; - } - } - - let next = 0, last = 0; - const edgefifo = new Uint32Array(32); - const vertexfifo = new Uint32Array(16); - - function decodeIndex(v) { - return (last += dezig(v)); - } - - let dstOffs = 0; - for (let i = 0; i < triCount; i++) { - const code = source[codeOffs++]; - const b0 = code >>> 4, b1 = code & 0x0F; - - if (b0 < 0x0F) { - const a = edgefifo[(b0 << 1) + 0], b = edgefifo[(b0 << 1) + 1]; - let c = -1; - - if (b1 === 0x00) { - c = next++; - pushfifo(vertexfifo, c); - } else if (b1 < 0x0D) { - c = vertexfifo[b1]; - } else if (b1 === 0x0D) { - c = --last; - pushfifo(vertexfifo, c); - } else if (b1 === 0x0E) { - c = ++last; - pushfifo(vertexfifo, c); - } else if (b1 === 0x0F) { - const v = readLEB128(); - c = decodeIndex(v); - pushfifo(vertexfifo, c); - } - - // fifo pushes happen backwards - pushfifo(edgefifo, b); pushfifo(edgefifo, c); - pushfifo(edgefifo, c); pushfifo(edgefifo, a); - - dst[dstOffs++] = a; - dst[dstOffs++] = b; - dst[dstOffs++] = c; - } else { // b0 === 0x0F - let a = -1, b = -1, c = -1; - - if (b1 < 0x0E) { - const e = source[codeauxOffs + b1]; - const z = e >>> 4, w = e & 0x0F; - - a = next++; - - if (z === 0x00) - b = next++; - else - b = vertexfifo[z - 1]; - - if (w === 0x00) - c = next++; - else - c = vertexfifo[w - 1]; - - pushfifo(vertexfifo, a); - if (z === 0x00) - pushfifo(vertexfifo, b); - if (w === 0x00) - pushfifo(vertexfifo, c); - } else { - const e = source[dataOffs++]; - if (e === 0x00) - next = 0; - - const z = e >>> 4, w = e & 0x0F; - - if (b1 === 0x0E) - a = next++; - else - a = decodeIndex(readLEB128()); - - if (z === 0x00) - b = next++; - else if (z === 0x0F) - b = decodeIndex(readLEB128()); - else - b = vertexfifo[z - 1]; - - if (w === 0x00) - c = next++; - else if (w === 0x0F) - c = decodeIndex(readLEB128()); - else - c = vertexfifo[w - 1]; - - pushfifo(vertexfifo, a); - if (z === 0x00 || z === 0x0F) - pushfifo(vertexfifo, b); - if (w === 0x00 || w === 0x0F) - pushfifo(vertexfifo, c); - } - - pushfifo(edgefifo, a); pushfifo(edgefifo, b); - pushfifo(edgefifo, b); pushfifo(edgefifo, c); - pushfifo(edgefifo, c); pushfifo(edgefifo, a); - - dst[dstOffs++] = a; - dst[dstOffs++] = b; - dst[dstOffs++] = c; - } - } + assert(source[0] === 0xE1); + assert(count % 3 === 0); + assert(byteStride === 2 || byteStride === 4); + + let dst; + if (byteStride === 2) + dst = new Uint16Array(target.buffer); + else + dst = new Uint32Array(target.buffer); + + const triCount = count / 3; + + let codeOffs = 0x01; + let dataOffs = codeOffs + triCount; + let codeauxOffs = source.length - 0x10; + + function readLEB128() { + let n = 0; + for (let i = 0; ; i += 7) { + const b = source[dataOffs++]; + n |= (b & 0x7F) << i; + + if (b < 0x80) + return n; + } + } + + let next = 0, last = 0; + const edgefifo = new Uint32Array(32); + const vertexfifo = new Uint32Array(16); + + function decodeIndex(v) { + return (last += dezig(v)); + } + + let dstOffs = 0; + for (let i = 0; i < triCount; i++) { + const code = source[codeOffs++]; + const b0 = code >>> 4, b1 = code & 0x0F; + + if (b0 < 0x0F) { + const a = edgefifo[(b0 << 1) + 0], b = edgefifo[(b0 << 1) + 1]; + let c = -1; + + if (b1 === 0x00) { + c = next++; + pushfifo(vertexfifo, c); + } else if (b1 < 0x0D) { + c = vertexfifo[b1]; + } else if (b1 === 0x0D) { + c = --last; + pushfifo(vertexfifo, c); + } else if (b1 === 0x0E) { + c = ++last; + pushfifo(vertexfifo, c); + } else if (b1 === 0x0F) { + const v = readLEB128(); + c = decodeIndex(v); + pushfifo(vertexfifo, c); + } + + // fifo pushes happen backwards + pushfifo(edgefifo, b); pushfifo(edgefifo, c); + pushfifo(edgefifo, c); pushfifo(edgefifo, a); + + dst[dstOffs++] = a; + dst[dstOffs++] = b; + dst[dstOffs++] = c; + } else { // b0 === 0x0F + let a = -1, b = -1, c = -1; + + if (b1 < 0x0E) { + const e = source[codeauxOffs + b1]; + const z = e >>> 4, w = e & 0x0F; + + a = next++; + + if (z === 0x00) + b = next++; + else + b = vertexfifo[z - 1]; + + if (w === 0x00) + c = next++; + else + c = vertexfifo[w - 1]; + + pushfifo(vertexfifo, a); + if (z === 0x00) + pushfifo(vertexfifo, b); + if (w === 0x00) + pushfifo(vertexfifo, c); + } else { + const e = source[dataOffs++]; + if (e === 0x00) + next = 0; + + const z = e >>> 4, w = e & 0x0F; + + if (b1 === 0x0E) + a = next++; + else + a = decodeIndex(readLEB128()); + + if (z === 0x00) + b = next++; + else if (z === 0x0F) + b = decodeIndex(readLEB128()); + else + b = vertexfifo[z - 1]; + + if (w === 0x00) + c = next++; + else if (w === 0x0F) + c = decodeIndex(readLEB128()); + else + c = vertexfifo[w - 1]; + + pushfifo(vertexfifo, a); + if (z === 0x00 || z === 0x0F) + pushfifo(vertexfifo, b); + if (w === 0x00 || w === 0x0F) + pushfifo(vertexfifo, c); + } + + pushfifo(edgefifo, a); pushfifo(edgefifo, b); + pushfifo(edgefifo, b); pushfifo(edgefifo, c); + pushfifo(edgefifo, c); pushfifo(edgefifo, a); + + dst[dstOffs++] = a; + dst[dstOffs++] = b; + dst[dstOffs++] = c; + } + } }; MeshoptDecoder.decodeIndexSequence = (target, count, byteStride, source) => { - assert(source[0] === 0xD1); - assert(byteStride === 2 || byteStride === 4); - - let dst; - if (byteStride === 2) - dst = new Uint16Array(target.buffer); - else - dst = new Uint32Array(target.buffer); - - let dataOffs = 0x01; - - function readLEB128() { - let n = 0; - for (let i = 0; ; i += 7) { - const b = source[dataOffs++]; - n |= (b & 0x7F) << i; - - if (b < 0x80) - return n; - } - } - - const last = new Uint32Array(2); - - for (let i = 0; i < count; i++) { - const v = readLEB128(); - const b = (v & 0x01); - const delta = dezig(v >>> 1); - dst[i] = (last[b] += delta); - } + assert(source[0] === 0xD1); + assert(byteStride === 2 || byteStride === 4); + + let dst; + if (byteStride === 2) + dst = new Uint16Array(target.buffer); + else + dst = new Uint32Array(target.buffer); + + let dataOffs = 0x01; + + function readLEB128() { + let n = 0; + for (let i = 0; ; i += 7) { + const b = source[dataOffs++]; + n |= (b & 0x7F) << i; + + if (b < 0x80) + return n; + } + } + + const last = new Uint32Array(2); + + for (let i = 0; i < count; i++) { + const v = readLEB128(); + const b = (v & 0x01); + const delta = dezig(v >>> 1); + dst[i] = (last[b] += delta); + } }; MeshoptDecoder.decodeGltfBuffer = (target, count, size, source, mode, filter) => { - var table = { - ATTRIBUTES: MeshoptDecoder.decodeVertexBuffer, - TRIANGLES: MeshoptDecoder.decodeIndexBuffer, - INDICES: MeshoptDecoder.decodeIndexSequence, - }; - assert(table[mode] !== undefined); - table[mode](target, count, size, source, filter); + var table = { + ATTRIBUTES: MeshoptDecoder.decodeVertexBuffer, + TRIANGLES: MeshoptDecoder.decodeIndexBuffer, + INDICES: MeshoptDecoder.decodeIndexSequence, + }; + assert(table[mode] !== undefined); + table[mode](target, count, size, source, filter); }; // node.js interface: From bdf4a36fb840ac159256348bf1159b8129e4b495 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 1 Jul 2024 13:59:56 -0700 Subject: [PATCH 138/581] js: Replace automatic export translation with export! comment This is resistant to formatting changes in the UMD sequence, so it will be compatible with Prettier. --- Makefile | 4 ++-- js/meshopt_decoder.js | 2 +- js/meshopt_encoder.js | 2 +- js/meshopt_simplifier.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 5c7c706232..61781bf413 100644 --- a/Makefile +++ b/Makefile @@ -161,9 +161,9 @@ js/meshopt_simplifier.js: build/simplifier.wasm tools/wasmpack.py sed -i "s#\(var wasm = \)\".*\";#\\1\"$$(cat build/simplifier.wasm | python3 tools/wasmpack.py)\";#" $@ js/%.module.js: js/%.js - sed '/UMD-style export/,$$d' <$< >$@ + sed '\#// export!#q' <$< >$@ sed -i "/\"use strict\";/d" $@ - sed -n "s#\s*module.exports = \(.*\);#export { \\1 };#p" <$< >>$@ + sed -i "s#// export! \(.*\)#export { \\1 };#" $@ $(DEMO): $(DEMO_OBJECTS) $(LIBRARY) $(CXX) $^ $(LDFLAGS) -o $@ diff --git a/js/meshopt_decoder.js b/js/meshopt_decoder.js index 0a53115141..65b90632ac 100644 --- a/js/meshopt_decoder.js +++ b/js/meshopt_decoder.js @@ -181,7 +181,7 @@ var MeshoptDecoder = (function() { }; })(); -// UMD-style export +// export! MeshoptDecoder if (typeof exports === 'object' && typeof module === 'object') module.exports = MeshoptDecoder; else if (typeof define === 'function' && define['amd']) diff --git a/js/meshopt_encoder.js b/js/meshopt_encoder.js index e0931ea3e9..5850ed96fc 100644 --- a/js/meshopt_encoder.js +++ b/js/meshopt_encoder.js @@ -196,7 +196,7 @@ var MeshoptEncoder = (function() { }; })(); -// UMD-style export for MeshoptEncoder +// export! MeshoptEncoder if (typeof exports === 'object' && typeof module === 'object') module.exports = MeshoptEncoder; else if (typeof define === 'function' && define['amd']) diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 77e09e5666..6102e37557 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -255,7 +255,7 @@ var MeshoptSimplifier = (function() { }; })(); -// UMD-style export for MeshoptSimplifier +// export! MeshoptSimplifier if (typeof exports === 'object' && typeof module === 'object') module.exports = MeshoptSimplifier; else if (typeof define === 'function' && define['amd']) From 8d649f99dbf0a006c3bf11c690a0a89cbacb10a3 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 1 Jul 2024 14:07:21 -0700 Subject: [PATCH 139/581] js: Switch to trailing comments for Wasm embedding Instead of relying on variable prefixes we now rely on comment suffixes and also handle both quotation mark styles. This makes the embedding resistant to formatting changes as long as the comment is kept in tact. --- Makefile | 8 ++++---- js/meshopt_decoder.js | 4 ++-- js/meshopt_decoder.module.js | 4 ++-- js/meshopt_encoder.js | 2 +- js/meshopt_encoder.module.js | 2 +- js/meshopt_simplifier.js | 2 +- js/meshopt_simplifier.module.js | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 61781bf413..27528be7e3 100644 --- a/Makefile +++ b/Makefile @@ -147,18 +147,18 @@ build/simplifier.wasm: $(WASM_SIMPLIFIER_SOURCES) js/meshopt_decoder.js: build/decoder_base.wasm build/decoder_simd.wasm tools/wasmpack.py sed -i "s#Built with clang.*#Built with $$($(WASMCC) --version | head -n 1 | sed 's/\s\+(.*//')#" $@ sed -i "s#Built from meshoptimizer .*#Built from meshoptimizer $$(cat src/meshoptimizer.h | grep -Po '(?<=version )[0-9.]+')#" $@ - sed -i "s#\(var wasm_base = \)\".*\";#\\1\"$$(cat build/decoder_base.wasm | python3 tools/wasmpack.py)\";#" $@ - sed -i "s#\(var wasm_simd = \)\".*\";#\\1\"$$(cat build/decoder_simd.wasm | python3 tools/wasmpack.py)\";#" $@ + sed -i "s#\([\"']\).*\(;\s*//\s*embed! base\)#\\1$$(cat build/decoder_base.wasm | python3 tools/wasmpack.py)\\1\\2#" $@ + sed -i "s#\([\"']\).*\(;\s*//\s*embed! simd\)#\\1$$(cat build/decoder_simd.wasm | python3 tools/wasmpack.py)\\1\\2#" $@ js/meshopt_encoder.js: build/encoder.wasm tools/wasmpack.py sed -i "s#Built with clang.*#Built with $$($(WASMCC) --version | head -n 1 | sed 's/\s\+(.*//')#" $@ sed -i "s#Built from meshoptimizer .*#Built from meshoptimizer $$(cat src/meshoptimizer.h | grep -Po '(?<=version )[0-9.]+')#" $@ - sed -i "s#\(var wasm = \)\".*\";#\\1\"$$(cat build/encoder.wasm | python3 tools/wasmpack.py)\";#" $@ + sed -i "s#\([\"']\).*\(;\s*//\s*embed! wasm\)#\\1$$(cat build/encoder.wasm | python3 tools/wasmpack.py)\\1\\2#" $@ js/meshopt_simplifier.js: build/simplifier.wasm tools/wasmpack.py sed -i "s#Built with clang.*#Built with $$($(WASMCC) --version | head -n 1 | sed 's/\s\+(.*//')#" $@ sed -i "s#Built from meshoptimizer .*#Built from meshoptimizer $$(cat src/meshoptimizer.h | grep -Po '(?<=version )[0-9.]+')#" $@ - sed -i "s#\(var wasm = \)\".*\";#\\1\"$$(cat build/simplifier.wasm | python3 tools/wasmpack.py)\";#" $@ + sed -i "s#\([\"']\).*\(;\s*//\s*embed! wasm\)#\\1$$(cat build/simplifier.wasm | python3 tools/wasmpack.py)\\1\\2#" $@ js/%.module.js: js/%.js sed '\#// export!#q' <$< >$@ diff --git a/js/meshopt_decoder.js b/js/meshopt_decoder.js index 65b90632ac..978f8ff902 100644 --- a/js/meshopt_decoder.js +++ b/js/meshopt_decoder.js @@ -4,8 +4,8 @@ var MeshoptDecoder = (function() { "use strict"; // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; - var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; + var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; // embed! base + var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; // embed! simd var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]); var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_decoder.module.js b/js/meshopt_decoder.module.js index fd5631edaf..6a3e919d1b 100644 --- a/js/meshopt_decoder.module.js +++ b/js/meshopt_decoder.module.js @@ -3,8 +3,8 @@ var MeshoptDecoder = (function() { // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; - var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; + var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq;w8Wqdbk;esezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9Uc;WFbGgocjdaocjd6EhDaicefhocbhqdnindndndnaeaq9nmbaDaeaq9RaqaDfae6Egkcsfglcl4cifcd4hxalc9WGgmTmecbhPawcjdfhsaohzinaraz9Rax6mvarazaxfgo9RcK6mvczhlcbhHinalgic9WfgOawcj;cbffhldndndndndnazaOco4fRbbaHcoG4ciGPlbedibkal9cb83ibalcwf9cb83ibxikalaoRblaoRbbgOco4gAaAciSgAE86bbawcj;cbfaifglcGfaoclfaAfgARbbaOcl4ciGgCaCciSgCE86bbalcVfaAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc7faAaCfgARbbaOciGgOaOciSgOE86bbalctfaAaOfgARbbaoRbegOco4gCaCciSgCE86bbalc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc93faAaCfgARbbaOciGgOaOciSgOE86bbalc94faAaOfgARbbaoRbdgOco4gCaCciSgCE86bbalc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbalc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbalc97faAaCfgARbbaOciGgOaOciSgOE86bbalc98faAaOfgORbbaoRbigoco4gAaAciSgAE86bbalc99faOaAfgORbbaocl4ciGgAaAciSgAE86bbalc9:faOaAfgORbbaocd4ciGgAaAciSgAE86bbalcufaOaAfglRbbaociGgoaociSgoE86bbalaofhoxdkalaoRbwaoRbbgOcl4gAaAcsSgAE86bbawcj;cbfaifglcGfaocwfaAfgARbbaOcsGgOaOcsSgOE86bbalcVfaAaOfgORbbaoRbegAcl4gCaCcsSgCE86bbalc7faOaCfgORbbaAcsGgAaAcsSgAE86bbalctfaOaAfgORbbaoRbdgAcl4gCaCcsSgCE86bbalc91faOaCfgORbbaAcsGgAaAcsSgAE86bbalc4faOaAfgORbbaoRbigAcl4gCaCcsSgCE86bbalc93faOaCfgORbbaAcsGgAaAcsSgAE86bbalc94faOaAfgORbbaoRblgAcl4gCaCcsSgCE86bbalc95faOaCfgORbbaAcsGgAaAcsSgAE86bbalc96faOaAfgORbbaoRbvgAcl4gCaCcsSgCE86bbalc97faOaCfgORbbaAcsGgAaAcsSgAE86bbalc98faOaAfgORbbaoRbogAcl4gCaCcsSgCE86bbalc99faOaCfgORbbaAcsGgAaAcsSgAE86bbalc9:faOaAfgORbbaoRbrgocl4gAaAcsSgAE86bbalcufaOaAfglRbbaocsGgoaocsSgoE86bbalaofhoxekalao8Pbb83bbalcwfaocwf8Pbb83bbaoczfhokdnaiam9pmbaHcdfhHaiczfhlarao9RcL0mekkaiam6mvaoTmvdnakTmbawaPfRbbhHawcj;cbfhlashiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkkascefhsaohzaPcefgPad9hmbxikkcbc99arao9Radcaadca0ESEhoxlkaoaxad2fhCdnakmbadhlinaoTmlarao9Rax6mlaoaxfhoalcufglmbkaChoxekcbhmawcjdfhAinarao9Rax6miawamfRbbhHawcj;cbfhlaAhiakhOinaialRbbgzce4cbazceG9R7aHfgH86bbaiadfhialcefhlaOcufgOmbkaAcefhAaoaxfhoamcefgmad9hmbkaChokabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqaombkc9:hoxekc9:hokavcj;ebf8Kjjjjbaok;cseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;oiliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabaiavcefciGfcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavciGfgkcd7cetfaD87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:OhDxekcjjjj94hDkabaiavcufciGfcetfaD87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohvxekcjjjj94hvkabakcetfav87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb"; // embed! base + var wasm_simd = "b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"; // embed! simd var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]); var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_encoder.js b/js/meshopt_encoder.js index 5850ed96fc..e84a5a194d 100644 --- a/js/meshopt_encoder.js +++ b/js/meshopt_encoder.js @@ -4,7 +4,7 @@ var MeshoptEncoder = (function() { "use strict"; // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; + var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; // embed! wasm var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_encoder.module.js b/js/meshopt_encoder.module.js index b95c1b6d29..c4867ef2b5 100644 --- a/js/meshopt_encoder.module.js +++ b/js/meshopt_encoder.module.js @@ -3,7 +3,7 @@ var MeshoptEncoder = (function() { // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; + var wasm = "b9H79TebbbeJq9Geueu9Geub9Gbb9Gvuuuuueu9Gduueu9Gluuuueu9Gvuuuuub9Gouuuuuub9Gluuuub9GiuuueuiKLdilevlevlooroowwvwbDDbelve9Weiiviebeoweuec:G;kekr;RiOo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWVbe8F9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949c919M9MWV9c9V919U9KbdE9TW79O9V9Wt9FW9U9J9V9KW9wWVtW949wWV79P9V9UbiY9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWVbl8E9TW79O9V9Wt9FW9U9J9V9KW69U9KW949c919M9MWV9c9V919U9Kbv8A9TW79O9V9Wt9FW9U9J9V9KW69U9KW949wWV79P9V9UboE9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JWbra9TW79O9V9Wt9FW9U9J9V9KW69U9KW949tWG91W9U9JW9c9V919U9KbwL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9p9JtbDK9TW79O9V9Wt9FW9U9J9V9KWS9P2tWV9r919HtbqL9TW79O9V9Wt9FW9U9J9V9KWS9P2tWVT949WbkE9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OWbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94J9H9J9OW9ttV9P9Wbsa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9WbzK9TW79O9V9Wt9F79W9Ht9P9H29t9VVt9sW9T9H9WbHl79IV9RbODwebcekdQXq;C9oLdbk;GqeKu8Jjjjjbcjo9Rgv8Kjjjjbcbhodnalcefae0mbabcbRbN:kjjbc:GeV86bbavcjdfcbcjdzNjjjb8AdnaiTmbavcjdfadalz:tjjjb8Akabaefhrabcefhwavalfcbcbcjdal9RalcFe0EzNjjjb8Aavavcjdfalz:tjjjbhDcj;abal9Uc;WFbGgecjdaecjd6Ehqcbhkindndnaiak9nmbaDcjlfcbcjdzNjjjb8Aaqaiak9Rakaqfai6Egxcsfgecl4cifcd4hmadakal2fhPdndndnaec9WGgsTmbcbhzaPhHawhOxekdnaxmbalheinaraw9Ram6miawcbamzNjjjbamfhwaecufgembxvkkcbhAaPhOinaDaAfRbbhCaDcjlfheaOhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkaraw9Ram6mdaOcefhOawcbamzNjjjbamfhwaAcefgAal9hmbxlkkindnaxTmbaDazfRbbhCaDcjlfheaHhoaxhXinaeaoRbbgQaC9RgCcetaC;acr4786bbaoalfhoaecefheaQhCaXcufgXmbkkaraO9Ram6mearaOcbamzNjjjbgLamfgw9RcK6mecbhKaDcjlfhOinaDcjlfaKfhYcwhAczhQceheindndnaegXce9hmbcuhoaYRbbmecbhodninaogecsSmeaecefhoaOaefcefRbbTmbkkcucbaecs6EhoxekaXcethocuaXtc;:bGcFb7hCcbheinaoaCaOaefRbb9nfhoaecefgecz9hmbkkaoaQaoaQ6geEhQaXaAaeEhAaXcetheaXcl6mbkdndndndnaAcufPdiebkaLaKco4fgeaeRbbcdciaAclSEaKci4coGtV86bbaAcw9hmeawaY8Pbb83bbawcwfaYcwf8Pbb83bbawczfhwxdkaLaKco4fgeaeRbbceaKci4coGtV86bbkdncwaA9Tg8Ambinawcb86bbawcefhwxbkkcuaAtcu7hYcbhEaOh3ina3hea8AhCcbhoinaeRbbgQaYcFeGgXaQaX6EaoaAtVhoaecefheaCcufgCmbkawao86bba3a8Afh3awcefhwaEa8AfgEcz6mbkcbheindnaOaefRbbgoaX6mbawao86bbawcefhwkaecefgecz9hmbkkdnaKczfgKas9pmbaOczfhOaraw9RcL0mekkaKas6meawTmeaHcefhHawhOazcefgzalSmixbkkcbhoxikcbhoaraw9Ralcaalca0E6mddnalc8F0mbawcbcaal9RgezNjjjbaefhwkawaDcjdfalz:tjjjbalfab9RhoxdkaDaPaxcufal2falz:tjjjb8Aaxakfhkawmbkcbhokavcjof8Kjjjjbaok9heeuaecaaeca0Eabcj;abae9Uc;WFbGgdcjdadcjd6Egdfcufad9Uae2adcl4cifcd4adV2fcefkmbcbabBdN:kjjbk:zse5u8Jjjjjbc;ae9Rgl8Kjjjjbcbhvdnaici9UgocHfae0mbabcbyd:e:kjjbgrc;GeV86bbalc;abfcFecjezNjjjb8AalcUfgw9cu83ibalc8WfgD9cu83ibalcyfgq9cu83ibalcafgk9cu83ibalcKfgx9cu83ibalczfgm9cu83ibal9cu83iwal9cu83ibabaefc9WfhPabcefgsaofhednaiTmbcmcsarcb9kgzEhHcbhOcbhAcbhCcbhXcbhQindnaeaP9nmbcbhvxikaQcufhvadaCcdtfgLydbhKaLcwfydbhYaLclfydbh8AcbhEdndndninalc;abfavcsGcitfgoydlh3dndndnaoydbgoaK9hmba3a8ASmekdnaoa8A9hmba3aY9hmbaEcefhExekaoaY9hmea3aK9hmeaEcdfhEkaEc870mdaXcufhvaLaEciGcx2goc:y1jjbfydbcdtfydbh3aLaocN1jjbfydbcdtfydbh8AaLaoc:q1jjbfydbcdtfydbhKcbhodnindnalavcsGcdtfydba39hmbaohYxdkcuhYavcufhvaocefgocz9hmbkkaOa3aOSgvaYce9iaYaH9oVgoGfhOdndndncbcsavEaYaoEgvcs9hmbarce9imba3a3aAa3cefaASgvEgAcefSmecmcsavEhvkasavaEcdtc;WeGV86bbavcs9hmea3aA9Rgvcetavc8F917hvinaeavcFb0crtavcFbGV86bbaecefheavcje6hoavcr4hvaoTmbka3hAxvkcPhvasaEcdtcPV86bba3hAkavTmiavaH9omicdhocehEaQhYxlkavcufhvaEclfgEc;ab9hmbkkdnaLceaYaOSceta8AaOSEcx2gvc:q1jjbfydbcdtfydbgKTaLavcN1jjbfydbcdtfydbg8AceSGaLavc:y1jjbfydbcdtfydbg3cdSGaOcb9hGazGg5ce9hmbaw9cu83ibaD9cu83ibaq9cu83ibak9cu83ibax9cu83ibam9cu83ibal9cu83iwal9cu83ibcbhOkcbhEaXcufgvhodnindnalaocsGcdtfydba8A9hmbaEhYxdkcuhYaocufhoaEcefgEcz9hmbkkcbhodnindnalavcsGcdtfydba39hmbaohExdkcuhEavcufhvaocefgocz9hmbkkaOaKaOSg8EfhLdndnaYcm0mbaYcefhYxekcbcsa8AaLSgvEhYaLavfhLkdndnaEcm0mbaEcefhExekcbcsa3aLSgvEhEaLavfhLkc9:cua8EEh8FcbhvaEaYcltVgacFeGhodndndninavcj1jjbfRbbaoSmeavcefgvcz9hmbxdkka5aKaO9havcm0VVmbasavc;WeV86bbxekasa8F86bbaeaa86bbaecefhekdna8EmbaKaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombkaKhAkdnaYcs9hmba8AaA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka8AhAkdnaEcs9hmba3aA9Rgvcetavc8F917hvinaeavcFb0gocrtavcFbGV86bbavcr4hvaecefheaombka3hAkalaXcdtfaKBdbaXcefcsGhvdndnaYPzbeeeeeeeeeeeeeebekalavcdtfa8ABdbaXcdfcsGhvkdndnaEPzbeeeeeeeeeeeeeebekalavcdtfa3BdbavcefcsGhvkcihoalc;abfaQcitfgEaKBdlaEa8ABdbaQcefcsGhYcdhEavhXaLhOxekcdhoalaXcdtfa3BdbcehEaXcefcsGhXaQhYkalc;abfaYcitfgva8ABdlava3Bdbalc;abfaQaEfcsGcitfgva3BdlavaKBdbascefhsaQaofcsGhQaCcifgCai6mbkkcbhvaeaP0mbcbhvinaeavfavcj1jjbfRbb86bbavcefgvcz9hmbkaeab9Ravfhvkalc;aef8KjjjjbavkZeeucbhddninadcefgdc8F0meceadtae6mbkkadcrfcFeGcr9Uci2cdfabci9U2cHfkmbcbabBd:e:kjjbk:ydewu8Jjjjjbcz9Rhlcbhvdnaicvfae0mbcbhvabcbRb:e:kjjbc;qeV86bbal9cb83iwabcefhoabaefc98fhrdnaiTmbcbhwcbhDindnaoar6mbcbskadaDcdtfydbgqalcwfawaqav9Rgvavc8F91gv7av9Rc507gwcdtfgkydb9Rgvc8E91c9:Gavcdt7awVhvinaoavcFb0gecrtavcFbGV86bbavcr4hvaocefhoaembkakaqBdbaqhvaDcefgDai9hmbkkcbhvaoar0mbaocbBbbaoab9RclfhvkavkBeeucbhddninadcefgdc8F0meceadtae6mbkkadcwfcFeGcr9Uab2cvfk:bvli99dui99ludnaeTmbcuadcetcuftcu7:Yhvdndncuaicuftcu7:YgoJbbbZMgr:lJbbb9p9DTmbar:Ohwxekcjjjj94hwkcbhicbhDinalclfIdbgrJbbbbJbbjZalIdbgq:lar:lMalcwfIdbgk:lMgr:varJbbbb9BEgrNhxaqarNhrdndnakJbbbb9GTmbaxhqxekJbbjZar:l:tgqaq:maxJbbbb9GEhqJbbjZax:l:tgxax:marJbbbb9GEhrkdndnalcxfIdbgxJbbj:;axJbbj:;9GEgkJbbjZakJbbjZ9FEavNJbbbZJbbb:;axJbbbb9GEMgx:lJbbb9p9DTmbax:Ohmxekcjjjj94hmkdndnaqJbbj:;aqJbbj:;9GEgxJbbjZaxJbbjZ9FEaoNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:OhPxekcjjjj94hPkdndnarJbbj:;arJbbj:;9GEgqJbbjZaqJbbjZ9FEaoNJbbbZJbbb:;arJbbbb9GEMgr:lJbbb9p9DTmbar:Ohsxekcjjjj94hskdndnadcl9hmbabaifgzas86bbazcifam86bbazcdfaw86bbazcefaP86bbxekabaDfgzas87ebazcofam87ebazclfaw87ebazcdfaP87ebkalczfhlaiclfhiaDcwfhDaecufgembkkk;hlld99eud99eudnaeTmbdndncuaicuftcu7:YgvJbbbZMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikaic;8FiGhrinabcofcicdalclfIdb:lalIdb:l9EgialcwfIdb:lalaicdtfIdb:l9EEgialcxfIdb:lalaicdtfIdb:l9EEgiarV87ebdndnJbbj:;JbbjZalaicdtfIdbJbbbb9DEgoalaicd7cdtfIdbJ;Zl:1ZNNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabcdfaq87ebdndnalaicefciGcdtfIdbJ;Zl:1ZNaoNgwJbbj:;awJbbj:;9GEgDJbbjZaDJbbjZ9FEavNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohqxekcjjjj94hqkabaq87ebdndnaoalaicufciGcdtfIdbJ;Zl:1ZNNgoJbbj:;aoJbbj:;9GEgwJbbjZawJbbjZ9FEavNJbbbZJbbb:;aoJbbbb9GEMgo:lJbbb9p9DTmbao:Ohixekcjjjj94hikabclfai87ebabcwfhbalczfhlaecufgembkkk:dvdxue998Jjjjjbcjd9Rgo8Kjjjjbadcd4hrdndndndnavcd9hmbadcl6meaohwarhDinawc:CuBdbawclfhwaDcufgDmbkaeTmiadcl6mdarcdthqalhkcbhxinaohwakhDarhminawawydbgPaDydbgscL4cFeGc:cufcbasEgsaPas9kEBdbaDclfhDawclfhwamcufgmmbkakaqfhkaxcefgxaeSmixbkkaeTmdxekaeTmekavcb9hadcl6gqVhzarcdthxavce9hhHcbhdindndndnaHmbaqmdc:CuhDalhwarhminaDawydbgPcL4cFeGc:cufcbaPEgPaDaP9kEhDawclfhwamcufgmmbxdkkc:CuhDazmbaohwalhmarhPinawamydbgscL4cFeGgkc8Aakc8A9kEc:cufcbasEBdbamclfhmawclfhwaPcufgPmbkkaqmbcbhwarhPinaDhmdnavceSmbaoawfydbhmkdndnalawfIdbgOcjjj;8iamai9RcefgmcLt9R::NJbbbZJbbb:;aOJbbbb9GEMgO:lJbbb9p9DTmbaO:Ohsxekcjjjj94hskabawfascFFFrGamcKtVBdbawclfhwaPcufgPmbkkabaxfhbalaxfhladcefgdae9hmbkkaocjdf8Kjjjjbk;HqdCui998Jjjjjbc:qd9Rgv8Kjjjjbavc:Sefcbc;KbzNjjjb8AcbhodnadTmbcbhoaiTmbdnabae9hmbavcuadcdtgradcFFFFi0Ecbyd:m:kjjbHjjjjbbgeBd:SeavceBd:mdaeabarz:tjjjb8Akavc:GefcwfcbBdbav9cb83i:Geavc:Gefaeadaiavc:Sefz:njjjbavyd:Gehwadci9UgDcbyd:m:kjjbHjjjjbbhravc:Sefavyd:mdgqcdtfarBdbavaqcefgkBd:mdarcbaDzNjjjbhxavc:SefakcdtfcuaicdtaicFFFFi0Ecbyd:m:kjjbHjjjjbbgmBdbavaqcdfgPBd:mdawhramhkinakalIdbalarydbgscwascw6Ecdtfc;ebfIdbMUdbarclfhrakclfhkaicufgimbkavc:SefaPcdtfcuaDcdtadcFFFF970Ecbyd:m:kjjbHjjjjbbgPBdbdnadci6mbaehraPhkaDhiinakamarydbcdtfIdbamarclfydbcdtfIdbMamarcwfydbcdtfIdbMUdbarcxfhrakclfhkaicufgimbkkaqcifhoavc;qbfhzavhravyd:KehHavyd:OehOcbhscbhkcbhAcehCinarhXcihQaeakci2gLcdtfgrydbhdarclfydbhqabaAcx2fgicwfarcwfydbgKBdbaiclfaqBdbaiadBdbaxakfce86bbazaKBdwazaqBdlazadBdbaPakcdtfcbBdbdnasTmbcihQaXhiinazaQcdtfaiydbgrBdbaQaraK9harad9haraq9hGGfhQaiclfhiascufgsmbkkaAcefhAcbhsinaOaHaeasaLfcdtfydbcdtgifydbcdtfgKhrawaifgqydbgdhidnadTmbdninarydbakSmearclfhraicufgiTmdxbkkaraKadcdtfc98fydbBdbaqaqydbcufBdbkascefgsci9hmbkdndnaQTmbcuhkJbbbbhYcbhqavyd:KehKavyd:OehLindndnawazaqcdtfydbcdtgsfydbgrmbaqcefhqxekaqcs0hiamasfgdIdbh8AadalcbaqcefgqaiEcdtfIdbalarcwarcw6Ecdtfc;ebfIdbMgEUdbaEa8A:thEarcdthiaLaKasfydbcdtfhrinaParydbgscdtfgdaEadIdbMg8AUdba8AaYaYa8A9DgdEhYasakadEhkarclfhraic98fgimbkkaqaQ9hmbkakcu9hmekaCaD9pmdindnaxaCfRbbmbaChkxdkaDaCcefgC9hmbxikkaQczaQcz6EhsazhraXhzakcu9hmbkkaocdtavc:Seffc98fhrdninaoTmearydbcbyd1:kjjbH:bjjjbbarc98fhraocufhoxbkkavc:qdf8Kjjjjbk;IlevucuaicdtgvaicFFFFi0Egocbyd:m:kjjbHjjjjbbhralalyd9GgwcdtfarBdbalawcefBd9GabarBdbaocbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdlcuadcdtadcFFFFi0Ecbyd:m:kjjbHjjjjbbhralalyd9GgocdtfarBdbalaocefBd9GabarBdwabydbcbavzNjjjb8Aadci9UhDdnadTmbabydbhoaehladhrinaoalydbcdtfgvavydbcefBdbalclfhlarcufgrmbkkdnaiTmbabydbhlabydlhrcbhvaihoinaravBdbarclfhralydbavfhvalclfhlaocufgombkkdnadci6mbabydlhrabydwhvcbhlinaecwfydbhoaeclfydbhdaraeydbcdtfgwawydbgwcefBdbavawcdtfalBdbaradcdtfgdadydbgdcefBdbavadcdtfalBdbaraocdtfgoaoydbgocefBdbavaocdtfalBdbaecxfheaDalcefgl9hmbkkdnaiTmbabydlheabydbhlinaeaeydbalydb9RBdbalclfhlaeclfheaicufgimbkkkQbabaeadaic:01jjbz:mjjjbkQbabaeadaic:C:jjjbz:mjjjbk9DeeuabcFeaicdtzNjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;Wkivuo99lu8Jjjjjbc;W;Gb9Rgl8Kjjjjbcbhvalcj;Gbfcbc;KbzNjjjb8AalcuadcdtadcFFFFi0Egocbyd:m:kjjbHjjjjbbgrBdj9GalceBd;G9GalcFFF;7rBdwal9cFFF;7;3FF:;Fb83dbalcFFF97Bd;S9Gal9cFFF;7FFF:;u83d;K9Gaicd4hwdndnadmbJFFuFhDJFFuuhqJFFuuhkJFFuFhxJFFuuhmJFFuFhPxekawcdthsaehzincbhiinalaifgHazaifIdbgDaHIdbgxaxaD9EEUdbalc;K;GbfaifgHaDaHIdbgxaxaD9DEUdbaiclfgicx9hmbkazasfhzavcefgvad9hmbkalIdwhqalId;S9GhDalIdlhkalId;O9GhxalIdbhmalId;K9GhPkdndnadTmbJbbbbJbbjZJbbbbaPam:tgPaPJbbbb9DEgPaxak:tgxaxaP9DEgxaDaq:tgDaDax9DEgD:vaDJbbbb9BEhDawcdthsarhHadhzindndnaDaeIdbam:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcv2c;j:KM;jbGhvdndnaDaeclfIdbak:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcq2cM;j:KMeGavVhvdndnaDaecwfIdbaq:tNJb;au9eNJbbbZMgx:lJbbb9p9DTmbax:Ohixekcjjjj94hikaHavaicztaicwtcj;GiGVaicsGVc:p;G:dKGcH2c;d;H:WKGcC2c:KM;j:KdGVBdbaeasfheaHclfhHazcufgzmbkalcbcj;GbzNjjjbhiarhHadheinaiaHydbgzcFrGcx2fgvavydbcefBdbaiazcq4cFrGcx2fgvavydlcefBdlaiazcC4cFrGcx2fgzazydwcefBdwaHclfhHaecufgembxdkkalcbcj;GbzNjjjb8AkcbhHcbhzcbhecbhvinalaHfgiydbhsaiazBdbaicwfgwydbhOawavBdbaiclfgiydbhwaiaeBdbasazfhzaOavfhvawaefheaHcxfgHcj;Gb9hmbkcbhHalaocbyd:m:kjjbHjjjjbbgiBd:e9GdnadTmbabhzinazaHBdbazclfhzadaHcefgH9hmbkabhHadhzinalaraHydbgecdtfydbcFrGcx2fgvavydbgvcefBdbaiavcdtfaeBdbaHclfhHazcufgzmbkaihHadhzinalaraHydbgecdtfydbcq4cFrGcx2fgvavydlgvcefBdlabavcdtfaeBdbaHclfhHazcufgzmbkabhHadhzinalaraHydbgecdtfydbcC4cFrGcx2fgvavydwgvcefBdwaiavcdtfaeBdbaHclfhHazcufgzmbkcbhHinabaiydbcdtfaHBdbaiclfhiadaHcefgH9hmbkkclhidninaic98Smealcj;Gbfaifydbcbyd1:kjjbH:bjjjbbaic98fhixbkkalc;W;Gbf8Kjjjjbk9teiucbcbyd:q:kjjbgeabcifc98GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:kjjbgeabcrfc94GfgbBd:q:kjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd:q:kjjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd:q:kjjbfgdBd:q:kjjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akkk:Iddbcjwk:edb4:h9w9N94:P:gW:j9O:ye9Pbbbbbbebbbdbbbebbbdbbbbbbbdbbbbbbbebbbbbbb:l29hZ;69:9kZ;N;76Z;rg97Z;z;o9xZ8J;B85Z;:;u9yZ;b;k9HZ:2;Z9DZ9e:l9mZ59A8KZ:r;T3Z:A:zYZ79OHZ;j4::8::Y:D9V8:bbbb9s:49:Z8R:hBZ9M9M;M8:L;z;o8:;8:PG89q;x:J878R:hQ8::M:B;e87bbbbbbjZbbjZbbjZ:E;V;N8::Y:DsZ9i;H;68:xd;R8:;h0838:;W:NoZbbbb:WV9O8:uf888:9i;H;68:9c9G;L89;n;m9m89;D8Ko8:bbbbf:8tZ9m836ZS:2AZL;zPZZ818EZ9e:lxZ;U98F8:819E;68:bc:eqkzebbbebbbdbbbaWbb"; // embed! wasm var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 6102e37557..25c378bcd1 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -4,7 +4,7 @@ var MeshoptSimplifier = (function() { "use strict"; // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; + var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; // embed! wasm var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index 5d4cd66524..74db1fb672 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -3,7 +3,7 @@ var MeshoptSimplifier = (function() { // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; + var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; // embed! wasm var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); From 75012cdf1052ade19e60faa8e56a7a1eec22c225 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 1 Jul 2024 18:41:15 -0700 Subject: [PATCH 140/581] Update USERS.md Increase GH star threshold to better match existing projects. --- USERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USERS.md b/USERS.md index 2087152bda..f6f19a6efa 100644 --- a/USERS.md +++ b/USERS.md @@ -1,6 +1,6 @@ meshoptimizer is widely used in the games industry as well as in many pipelines for processing 3D content for real-time rendering. This document contains a small selection of projects that rely on meshoptimizer. -For brevity, the projects listed below are limited to commercial software or open source software that has 100+ stars on GitHub. Please feel free to contribute additions via pull requests. +For brevity, the projects listed below are limited to commercial software or open source software that has 1000+ stars on GitHub. Please feel free to contribute additions via pull requests. # Games From cc0820f94f6dc6c2c81bb2894f91797625983403 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Jul 2024 10:47:46 -0700 Subject: [PATCH 141/581] Use consistent variable references via $() in Makefile --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 27528be7e3..3cb9df8ec8 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ $(BUILD)/gltfpack: $(GLTFPACK_OBJECTS) $(LIBRARY) gltfpack.wasm: gltf/library.wasm -gltf/library.wasm: ${LIBRARY_SOURCES} ${GLTFPACK_SOURCES} +gltf/library.wasm: $(LIBRARY_SOURCES) $(GLTFPACK_SOURCES) $(WASMCC) $^ -o $@ -Os -DNDEBUG --target=wasm32-wasi --sysroot=$(WASIROOT) -nostartfiles -Wl,--no-entry -Wl,--export=pack -Wl,--export=malloc -Wl,--export=free -Wl,--export=__wasm_call_ctors -Wl,-s -Wl,--allow-undefined-file=gltf/wasistubs.txt build/decoder_base.wasm: $(WASM_DECODER_SOURCES) @@ -174,16 +174,16 @@ vcachetuner: tools/vcachetuner.cpp tools/objloader.cpp $(LIBRARY) codecbench: tools/codecbench.cpp $(LIBRARY) $(CXX) $^ $(CXXFLAGS) $(LDFLAGS) -o $@ -codecbench.js: tools/codecbench.cpp ${LIBRARY_SOURCES} +codecbench.js: tools/codecbench.cpp $(LIBRARY_SOURCES) emcc $^ -O3 -g -DNDEBUG -s TOTAL_MEMORY=268435456 -s SINGLE_FILE=1 -o $@ -codecbench-simd.js: tools/codecbench.cpp ${LIBRARY_SOURCES} +codecbench-simd.js: tools/codecbench.cpp $(LIBRARY_SOURCES) emcc $^ -O3 -g -DNDEBUG -s TOTAL_MEMORY=268435456 -s SINGLE_FILE=1 -msimd128 -o $@ -codecbench.wasm: tools/codecbench.cpp ${LIBRARY_SOURCES} +codecbench.wasm: tools/codecbench.cpp $(LIBRARY_SOURCES) $(WASMCC) $^ -fno-exceptions --target=wasm32-wasi --sysroot=$(WASIROOT) -lc++ -lc++abi -O3 -g -DNDEBUG -o $@ -codecbench-simd.wasm: tools/codecbench.cpp ${LIBRARY_SOURCES} +codecbench-simd.wasm: tools/codecbench.cpp $(LIBRARY_SOURCES) $(WASMCC) $^ -fno-exceptions --target=wasm32-wasi --sysroot=$(WASIROOT) -lc++ -lc++abi -O3 -g -DNDEBUG -msimd128 -o $@ codecfuzz: tools/codecfuzz.cpp src/vertexcodec.cpp src/indexcodec.cpp From 6749214e71eb7316fdbcb0abc8b20b7a070f201f Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Jul 2024 11:09:21 -0700 Subject: [PATCH 142/581] gltfpack: Fix minor memory leak when decompressing invalid files If the glTF structure of EXT_meshopt_compression was invalid or decoding failed, we would leak the result buffer; we now make sure we record the pointer early -- if decoding fails we will free it in cgltf_free later. --- gltf/parsegltf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index f83356b70e..d8feb905ba 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -531,6 +531,8 @@ static cgltf_result decompressMeshopt(cgltf_data* data) if (!result) return cgltf_result_out_of_memory; + data->buffer_views[i].data = result; + int rc = -1; switch (mc->mode) @@ -571,8 +573,6 @@ static cgltf_result decompressMeshopt(cgltf_data* data) default: break; } - - data->buffer_views[i].data = result; } return cgltf_result_success; From fc5a77691021b9230e5a3b233b146ed2a2071aab Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Jul 2024 11:42:46 -0700 Subject: [PATCH 143/581] gltfpack: Work around clang analyzer false positive data is non-null if result is cgltf_result_success; clang analyzer doesn't track this correctly and as such some other functions may trigger analysis false positives on a possible nullptr deref. --- gltf/parsegltf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index d8feb905ba..7d14be33f2 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -621,7 +621,7 @@ cgltf_data* parseGltf(const char* path, std::vector& meshes, std::vectorbin) + if (result == cgltf_result_success && !data->bin) freeFile(data); result = (result == cgltf_result_success) ? cgltf_load_buffers(&options, data, path) : result; From 0b00a8a122c72f4dd50c3681221294b9b9a37a5f Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 2 Jul 2024 11:57:09 -0700 Subject: [PATCH 144/581] vertexfilter: Work around clang analyzer false positive The mode is one of three values, and the code in the inner loop assumes component_exp is filled for one of two modes; however, if the mode is ever set to something else, we will read uninitialized component_exp[] component. An assert helps clang see the flow properly. --- src/vertexfilter.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vertexfilter.cpp b/src/vertexfilter.cpp index 4b5f444f04..8a87b299fe 100644 --- a/src/vertexfilter.cpp +++ b/src/vertexfilter.cpp @@ -1010,6 +1010,11 @@ void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, in component_exp[j] = (min_exp < e) ? e : min_exp; } } + else + { + // the code below assumes component_exp is initialized outside of the loop + assert(mode == meshopt_EncodeExpSharedComponent); + } for (size_t j = 0; j < stride_float; ++j) { @@ -1020,7 +1025,6 @@ void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, in // compute renormalized rounded mantissa for each component int mmask = (1 << 24) - 1; - int m = int(v[j] * optexp2(-exp) + (v[j] >= 0 ? 0.5f : -0.5f)); d[j] = (m & mmask) | (unsigned(exp) << 24); From a4cba13250d05ee0257db90eecc56e3b49eab2e5 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 3 Jul 2024 16:02:39 -0700 Subject: [PATCH 145/581] Fix minor formatting discrepancies in meshoptimizer.h meshoptimizer.h isn't part of clang-format set due to excessive indentation, so some stylistic choices aren't automatically applied. --- src/meshoptimizer.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index cb3745a2cc..8b2345263d 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -729,8 +729,8 @@ class meshopt_Allocator typedef StorageT Storage; meshopt_Allocator() - : blocks() - , count(0) + : blocks() + , count(0) { } @@ -740,7 +740,8 @@ class meshopt_Allocator Storage::deallocate(blocks[i - 1]); } - template T* allocate(size_t size) + template + T* allocate(size_t size) { assert(count < sizeof(blocks) / sizeof(blocks[0])); T* result = static_cast(Storage::allocate(size > size_t(-1) / sizeof(T) ? size_t(-1) : size * sizeof(T))); @@ -761,8 +762,10 @@ class meshopt_Allocator }; // This makes sure that allocate/deallocate are lazily generated in translation units that need them and are deduplicated by the linker -template void* (MESHOPTIMIZER_ALLOC_CALLCONV *meshopt_Allocator::StorageT::allocate)(size_t) = operator new; -template void (MESHOPTIMIZER_ALLOC_CALLCONV *meshopt_Allocator::StorageT::deallocate)(void*) = operator delete; +template +void* (MESHOPTIMIZER_ALLOC_CALLCONV *meshopt_Allocator::StorageT::allocate)(size_t) = operator new; +template +void (MESHOPTIMIZER_ALLOC_CALLCONV *meshopt_Allocator::StorageT::deallocate)(void*) = operator delete; #endif /* Inline implementation for C++ templated wrappers */ From 3399183f2e6b81720a586d3c2cb4ab92330b6677 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 3 Jul 2024 16:13:50 -0700 Subject: [PATCH 146/581] Add make symbols to show the shared object export table This is convenient to make sure symbols aren't acciendtally exposed unnecessarily. Note that for now this builds the code with default visibility settings, instead of using special shared object setup we have in CMake, so in debug mode there will be extra inline symbols. Also this needs to build a .so with special flags so we do this via an amalgamated source file which helpfully tests that amalgamation is actually supported. --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 3cb9df8ec8..fc32ef24ba 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,9 @@ format: js: js/meshopt_decoder.js js/meshopt_decoder.module.js js/meshopt_encoder.js js/meshopt_encoder.module.js js/meshopt_simplifier.js js/meshopt_simplifier.module.js +symbols: $(BUILD)/amalgamated.so + nm $< -U -g + gltfpack: $(BUILD)/gltfpack ln -fs $^ $@ @@ -192,6 +195,10 @@ codecfuzz: tools/codecfuzz.cpp src/vertexcodec.cpp src/indexcodec.cpp $(LIBRARY): $(LIBRARY_OBJECTS) ar rcs $@ $^ +$(BUILD)/amalgamated.so: $(LIBRARY_SOURCES) + @mkdir -p $(dir $@) + cat $^ | $(CXX) $(CXXFLAGS) -x c++ - -I src/ -o $@ -shared -fPIC + $(BUILD)/%.cpp.o: %.cpp @mkdir -p $(dir $@) $(CXX) $< $(CXXFLAGS) -c -MMD -MP -o $@ From d381655ab9cf494181c6774739fe2048ef559b3d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 4 Jul 2024 10:54:27 -0700 Subject: [PATCH 147/581] vertexcodec: Work around clang analyzer false positive clang analyzer doesn't realize vertex_count <= vertex_count_aligned holds (which it does unless addition overflows, which is impossible with size_t due to a memory limit on vertex inputs, but also we bounds check vertex count!), and then thinks that we might be writing less than vertex_count elements to the output buffer. This change fixes this, and also undefs a forgotten define as a drive-by. --- src/vertexcodec.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vertexcodec.cpp b/src/vertexcodec.cpp index 94f7a1adc2..17324362c8 100644 --- a/src/vertexcodec.cpp +++ b/src/vertexcodec.cpp @@ -383,6 +383,7 @@ static const unsigned char* decodeVertexBlock(const unsigned char* data, const u unsigned char transposed[kVertexBlockSizeBytes]; size_t vertex_count_aligned = (vertex_count + kByteGroupSize - 1) & ~(kByteGroupSize - 1); + assert(vertex_count <= vertex_count_aligned); for (size_t k = 0; k < vertex_size; ++k) { @@ -1246,3 +1247,4 @@ int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t ve #undef SIMD_WASM #undef SIMD_FALLBACK #undef SIMD_TARGET +#undef SIMD_LATENCYOPT From 8bb3438c152ef4da2b1ee26613942d0fe7a60811 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 5 Jul 2024 10:25:25 -0700 Subject: [PATCH 148/581] Update README.md Remove extraneous sentence. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 6814e98413..0c65c247b7 100644 --- a/README.md +++ b/README.md @@ -101,8 +101,6 @@ When performing the overdraw optimization you have to specify a floating-point t After the final triangle order has been established, we still can optimize the vertex buffer for memory efficiency. Before running the vertex shader GPU has to fetch the vertex attributes from the vertex buffer; the fetch is usually backed by a memory cache, and as such optimizing the data for the locality of memory access is important. You can do this by running this code: -To optimize the index/vertex buffers for vertex fetch efficiency, call: - ```c++ meshopt_optimizeVertexFetch(vertices, indices, index_count, vertices, vertex_count, sizeof(Vertex)); ``` From 639de4d0fee41f4cdbe75134d974ea75ec765121 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 8 Jul 2024 10:50:49 -0700 Subject: [PATCH 149/581] gltfpack: Optionally keep unused vertex attributes When a new option `-kv` is specified, gltfpack no longer removes unused vertex attributes (v mirrors existing usage for -sv and -vX). This can be useful in a few cases: - Normals may be needed for custom vertex processing even if materials are unlit - Tangents may be needed for custom shading at runtime that gltfpack isn't aware of - Tangents may help with simplification across UV mirroring seams - Texture coordinates may be needed at runtime even if this is not indicated by any material textures; in this case, -vtf should be used to disable UV quantization --- gltf/gltfpack.cpp | 8 +++++++- gltf/gltfpack.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index ee46fa6a71..ab68c0fe50 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -369,7 +369,8 @@ static void process(cgltf_data* data, const char* input_path, const char* output mi.unlit &= vi.unlit; } - filterStreams(mesh, mi); + if (!settings.keep_attributes) + filterStreams(mesh, mi); } mergeMeshMaterials(data, meshes, settings); @@ -1308,6 +1309,10 @@ int main(int argc, char** argv) { settings.keep_extras = true; } + else if (strcmp(arg, "-kv") == 0) + { + settings.keep_attributes = true; + } else if (strcmp(arg, "-mm") == 0) { settings.mesh_merge = true; @@ -1531,6 +1536,7 @@ int main(int argc, char** argv) fprintf(stderr, "\nVertex attributes:\n"); fprintf(stderr, "\t-vtf: use floating point attributes for texture coordinates\n"); fprintf(stderr, "\t-vnf: use floating point attributes for normals\n"); + fprintf(stderr, "\t-kv: keep source vertex attributes even if they aren't used\n"); fprintf(stderr, "\nAnimations:\n"); fprintf(stderr, "\t-at N: use N-bit quantization for translations (default: 16; N should be between 1 and 24)\n"); fprintf(stderr, "\t-ar N: use N-bit quantization for rotations (default: 12; N should be between 4 and 16)\n"); diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index 2af672334f..10d436d43a 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -129,6 +129,7 @@ struct Settings bool keep_nodes; bool keep_materials; bool keep_extras; + bool keep_attributes; bool mesh_merge; bool mesh_instancing; From 769e168df5f32d47a7d126794d6fe69c0044cb77 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 8 Jul 2024 14:52:50 -0700 Subject: [PATCH 150/581] Switch from c++98 to gnu++98 for Makefile builds std=c++98 has an unfortunate side effect in that it causes gcc to emit calls to fabsf/sqrtf; this significantly affects performance of several algorithms, making benchmarks not fully representative. We could likely just switch to C++11 at this point but there isn't a specific reason to go there right now other than unifying build settings between gltfpack and the library, so we can do that separately. On the flip side, omitting standard version results in C++17 being selected automatically which pulls in much more code from standard headers, slowing compilation down. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fc32ef24ba..2e6a838bfd 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ LIBRARY=$(BUILD)/libmeshoptimizer.a DEMO=$(BUILD)/meshoptimizer CFLAGS=-g -Wall -Wextra -Werror -std=c89 -CXXFLAGS=-g -Wall -Wextra -Wshadow -Wno-missing-field-initializers -Werror -std=c++98 +CXXFLAGS=-g -Wall -Wextra -Wshadow -Wno-missing-field-initializers -Werror -std=gnu++98 LDFLAGS= $(GLTFPACK_OBJECTS): CXXFLAGS+=-std=c++11 From f16ee88ef43431cddf2c65406976d0636255a628 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 10 Jul 2024 11:13:29 -0700 Subject: [PATCH 151/581] gltfpack: Minor mesh processing refactoring The logic for detaching mesh from nodes is fairly complex but it's a little difficult to separate into individual components due to multiple scenes handling, so for now just extract it into a separate function to make the high level processing flow easier to read. --- gltf/gltfpack.cpp | 129 ++++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 66 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index ab68c0fe50..e6afb21cd0 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -250,6 +250,68 @@ static bool canTransformMesh(const Mesh& mesh) return true; } +static void detachMesh(Mesh& mesh, cgltf_data* data, const std::vector& nodes, const Settings& settings) +{ + // mesh is already instanced, skip + if (!mesh.instances.empty()) + return; + + // mesh is already world space, skip + if (mesh.nodes.empty()) + return; + + // note: when -kn is specified, we keep mesh-node attachment so that named nodes can be transformed + if (settings.keep_nodes) + return; + + // we keep skinned meshes or meshes with morph targets as is + // in theory we could transform both, but in practice transforming morph target meshes is more involved, + // and reparenting skinned meshes leads to incorrect bounding box generated in three.js + if (mesh.skin || mesh.targets) + return; + + bool any_animated = false; + for (size_t j = 0; j < mesh.nodes.size(); ++j) + any_animated |= nodes[mesh.nodes[j] - data->nodes].animated; + + // animated meshes will be anchored to the same node that they used to be in to retain the animation + if (any_animated) + return; + + int scene = nodes[mesh.nodes[0] - data->nodes].scene; + bool any_other_scene = false; + for (size_t j = 0; j < mesh.nodes.size(); ++j) + any_other_scene |= scene != nodes[mesh.nodes[j] - data->nodes].scene; + + // we only merge instances when all nodes have a single consistent scene + if (scene < 0 || any_other_scene) + return; + + // we only merge multiple instances together if requested + // this often makes the scenes faster to render by reducing the draw call count, but can result in larger files + if (mesh.nodes.size() > 1 && !settings.mesh_merge && !settings.mesh_instancing) + return; + + // prefer instancing if possible, use merging otherwise + if (mesh.nodes.size() > 1 && settings.mesh_instancing) + { + mesh.instances.resize(mesh.nodes.size()); + + for (size_t j = 0; j < mesh.nodes.size(); ++j) + cgltf_node_transform_world(mesh.nodes[j], mesh.instances[j].data); + + mesh.nodes.clear(); + mesh.scene = scene; + } + else if (canTransformMesh(mesh)) + { + mergeMeshInstances(mesh); + + assert(mesh.nodes.empty()); + mesh.scene = scene; + } +} + static bool isExtensionSupported(const ExtensionInfo* extensions, size_t count, const char* name) { for (size_t i = 0; i < count; ++i) @@ -269,9 +331,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output } for (size_t i = 0; i < animations.size(); ++i) - { processAnimation(animations[i], settings); - } std::vector nodes(data->nodes_count); @@ -279,68 +339,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output markAnimated(data, nodes, animations); for (size_t i = 0; i < meshes.size(); ++i) - { - Mesh& mesh = meshes[i]; - - // mesh is already instanced, skip - if (!mesh.instances.empty()) - continue; - - // mesh is already world space, skip - if (mesh.nodes.empty()) - continue; - - // note: when -kn is specified, we keep mesh-node attachment so that named nodes can be transformed - if (settings.keep_nodes) - continue; - - // we keep skinned meshes or meshes with morph targets as is - // in theory we could transform both, but in practice transforming morph target meshes is more involved, - // and reparenting skinned meshes leads to incorrect bounding box generated in three.js - if (mesh.skin || mesh.targets) - continue; - - bool any_animated = false; - for (size_t j = 0; j < mesh.nodes.size(); ++j) - any_animated |= nodes[mesh.nodes[j] - data->nodes].animated; - - // animated meshes will be anchored to the same node that they used to be in to retain the animation - if (any_animated) - continue; - - int scene = nodes[mesh.nodes[0] - data->nodes].scene; - bool any_other_scene = false; - for (size_t j = 0; j < mesh.nodes.size(); ++j) - any_other_scene |= scene != nodes[mesh.nodes[j] - data->nodes].scene; - - // we only merge instances when all nodes have a single consistent scene - if (scene < 0 || any_other_scene) - continue; - - // we only merge multiple instances together if requested - // this often makes the scenes faster to render by reducing the draw call count, but can result in larger files - if (mesh.nodes.size() > 1 && !settings.mesh_merge && !settings.mesh_instancing) - continue; - - // prefer instancing if possible, use merging otherwise - if (mesh.nodes.size() > 1 && settings.mesh_instancing) - { - mesh.instances.resize(mesh.nodes.size()); - - for (size_t j = 0; j < mesh.nodes.size(); ++j) - cgltf_node_transform_world(mesh.nodes[j], mesh.instances[j].data); - - mesh.nodes.clear(); - mesh.scene = scene; - } - else if (canTransformMesh(mesh)) - { - mergeMeshInstances(mesh); - - assert(mesh.nodes.empty()); - mesh.scene = scene; - } - } + detachMesh(meshes[i], data, nodes, settings); // material information is required for mesh and image processing std::vector materials(data->materials_count); @@ -406,9 +405,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output #endif for (size_t i = 0; i < meshes.size(); ++i) - { processMesh(meshes[i], settings); - } #ifndef NDEBUG meshes.insert(meshes.end(), debug_meshes.begin(), debug_meshes.end()); From 93c0013dae3ba419adddf762bffcca9af9f4b52b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 11 Jul 2024 11:53:17 -0700 Subject: [PATCH 152/581] simplify: Implement internal flag for topology debug information We have been relying on smuggling the kind/loop info computed during classification via meshopt_simplifyDebug global pointers. This information is valuable to visualize, and there's future improvements to classification that would need to be debugged, so it's not ready to remove but exposing this as globals results in issues as it expands the exported API surface, making it different between release & debug builds. Instead, this change adds a way to request this via an option bit, and return it via indices[] - instead of per-vertex information, we return this per-triangle-corner. It's not exactly identical, as there's some redundancy, but per-corner metadata is nice in general and this is generally sufficient to do the requisite visualization. The newly added option bit is *not* part of the official API surface - the format of the data may change at any point, and the entire feature may get dropped at any point once it stops being useful. --- src/simplifier.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index e59b4afcd9..6e93ea53e3 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -1546,8 +1546,13 @@ static float interpolate(float y, float x0, float y0, float x1, float y1, float } // namespace meshopt +// Note: this is only exposed for debug visualization purposes; do *not* use +enum +{ + meshopt_SimplifyInternalDebug = 1 << 30 +}; + #ifndef NDEBUG -// Note: this is only exposed for debug visualization purposes; do *not* use these in debug builds MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = NULL; MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = NULL; MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = NULL; @@ -1561,7 +1566,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(target_index_count <= index_count); - assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute)) == 0); + assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute | meshopt_SimplifyInternalDebug)) == 0); assert(vertex_attributes_stride >= attribute_count * sizeof(float) && vertex_attributes_stride <= 256); assert(vertex_attributes_stride % sizeof(float) == 0); assert(attribute_count <= kMaxAttributes); @@ -1705,6 +1710,21 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic printf("result: %d triangles, error: %e; total %d passes\n", int(result_count / 3), sqrtf(result_error), int(pass_count)); #endif + // if debug visualization data is requested, fill it instead of index data; for simplicity, this doesn't work with sparsity + if ((options & meshopt_SimplifyInternalDebug) && !sparse_remap) + { + assert(Kind_Count <= 8 && vertex_count < (1 << 28)); // 3 bit kind, 1 bit loop + + for (size_t i = 0; i < result_count; i += 3) + { + unsigned int a = result[i + 0], b = result[i + 1], c = result[i + 2]; + + result[i + 0] |= (vertex_kind[a] << 28) | (unsigned(loop[a] == b || loopback[b] == a) << 31); + result[i + 1] |= (vertex_kind[b] << 28) | (unsigned(loop[b] == c || loopback[c] == b) << 31); + result[i + 2] |= (vertex_kind[c] << 28) | (unsigned(loop[c] == a || loopback[a] == c) << 31); + } + } + #ifndef NDEBUG if (meshopt_simplifyDebugKind) memcpy(meshopt_simplifyDebugKind, vertex_kind, vertex_count); From b42333e295dba59fd3d1b0eb30f0d0c4d6446945 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 11 Jul 2024 12:10:26 -0700 Subject: [PATCH 153/581] gltfpack: Switch to SimplifyInternalDebug for debugSimplify This code reworks the debug visualization for simplification to use new internal feature that communicates metadata via index data. For now we draw loops even for locked vertices and don't make an attempt to deduplicate points or lines, as visualization performance is not critical, and locked loops actually make it easier to debug in some cases. --- gltf/mesh.cpp | 78 +++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index a956569ab8..99950767ba 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -527,8 +527,13 @@ static Stream* getStream(Mesh& mesh, cgltf_attribute_type type, int index = 0) return NULL; } -static void simplifyMesh(Mesh& mesh, float threshold, bool attributes, bool aggressive, bool lock_borders) +static void simplifyMesh(Mesh& mesh, float threshold, bool attributes, bool aggressive, bool lock_borders, bool debug = false) { + enum + { + meshopt_SimplifyInternalDebug = 1 << 30 + }; + assert(mesh.type == cgltf_primitive_type_triangles); if (mesh.indices.empty()) @@ -543,7 +548,11 @@ static void simplifyMesh(Mesh& mesh, float threshold, bool attributes, bool aggr size_t target_index_count = size_t(double(mesh.indices.size() / 3) * threshold) * 3; float target_error = 1e-2f; float target_error_aggressive = 1e-1f; - unsigned int options = lock_borders ? meshopt_SimplifyLockBorder : 0; + unsigned int options = 0; + if (lock_borders) + options |= meshopt_SimplifyLockBorder; + if (debug) + options |= meshopt_SimplifyInternalDebug; const Stream* attr = getStream(mesh, cgltf_attribute_type_color); attr = attr ? attr : getStream(mesh, cgltf_attribute_type_normal); @@ -784,10 +793,6 @@ void processMesh(Mesh& mesh, const Settings& settings) } #ifndef NDEBUG -extern MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind; -extern MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop; -extern MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack; - void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio, bool attributes) { Mesh mesh = source; @@ -799,27 +804,9 @@ void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio, bo reindexMesh(mesh); filterTriangles(mesh); - // before simplification we need to setup target kind/loop arrays size_t vertex_count = mesh.streams[0].data.size(); - std::vector kind(vertex_count); - std::vector loop(vertex_count); - std::vector loopback(vertex_count); - std::vector live(vertex_count); - - meshopt_simplifyDebugKind = &kind[0]; - meshopt_simplifyDebugLoop = &loop[0]; - meshopt_simplifyDebugLoopBack = &loopback[0]; - - simplifyMesh(mesh, ratio, attributes, /* aggressive= */ false, /* lock_borders= */ false); - - meshopt_simplifyDebugKind = NULL; - meshopt_simplifyDebugLoop = NULL; - meshopt_simplifyDebugLoopBack = NULL; - - // fill out live info - for (size_t i = 0; i < mesh.indices.size(); ++i) - live[mesh.indices[i]] = true; + simplifyMesh(mesh, ratio, attributes, /* aggressive= */ false, /* lock_borders= */ false, /* debug= */ true); // color palette for display static const Attr kPalette[] = { @@ -850,38 +837,37 @@ void debugSimplify(const Mesh& source, Mesh& kinds, Mesh& loops, float ratio, bo // transform kind/loop data into lines & points Stream colors = {cgltf_attribute_type_color}; - colors.data.resize(vertex_count); - - for (size_t i = 0; i < vertex_count; ++i) - colors.data[i] = kPalette[kind[i]]; + colors.data.resize(vertex_count, kPalette[0]); kinds.type = cgltf_primitive_type_points; - - kinds.streams.push_back(colors); - - for (size_t i = 0; i < vertex_count; ++i) - if (live[i] && kind[i] != 0) - kinds.indices.push_back(unsigned(i)); - loops.type = cgltf_primitive_type_lines; - loops.streams.push_back(colors); - - for (size_t i = 0; i < vertex_count; ++i) - if (live[i] && (kind[i] == 1 || kind[i] == 2)) + for (size_t i = 0; i < mesh.indices.size(); i += 3) + { + for (int k = 0; k < 3; ++k) { - if (loop[i] != ~0u && live[loop[i]]) + const unsigned int mask = (1 << 28) - 1; + unsigned int v = mesh.indices[i + k]; + unsigned int next = mesh.indices[i + (k + 1) % 3]; + unsigned int vk = (v >> 28) & 7; + unsigned int vl = v >> 31; + + if (vk) { - loops.indices.push_back(unsigned(i)); - loops.indices.push_back(loop[i]); + colors.data[v & mask] = kPalette[vk]; + kinds.indices.push_back(v & mask); } - if (loopback[i] != ~0u && live[loopback[i]]) + if (vl) { - loops.indices.push_back(loopback[i]); - loops.indices.push_back(unsigned(i)); + loops.indices.push_back(v & mask); + loops.indices.push_back(next & mask); } } + } + + kinds.streams.push_back(colors); + loops.streams.push_back(colors); } void debugMeshlets(const Mesh& source, Mesh& meshlets, int max_vertices, bool scan) From 3c6f9b0e25d56dc4b501ddb855f034c594998444 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 11 Jul 2024 12:13:07 -0700 Subject: [PATCH 154/581] simplify: Clean up old meshopt_simplifyDebug symbols We no longer rely on these in gltfpack. --- src/simplifier.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 6e93ea53e3..d19e25fd5c 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -1552,12 +1552,6 @@ enum meshopt_SimplifyInternalDebug = 1 << 30 }; -#ifndef NDEBUG -MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = NULL; -MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = NULL; -MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = NULL; -#endif - size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { using namespace meshopt; @@ -1725,17 +1719,6 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic } } -#ifndef NDEBUG - if (meshopt_simplifyDebugKind) - memcpy(meshopt_simplifyDebugKind, vertex_kind, vertex_count); - - if (meshopt_simplifyDebugLoop) - memcpy(meshopt_simplifyDebugLoop, loop, vertex_count * sizeof(unsigned int)); - - if (meshopt_simplifyDebugLoopBack) - memcpy(meshopt_simplifyDebugLoopBack, loopback, vertex_count * sizeof(unsigned int)); -#endif - // convert resulting indices back into the dense space of the larger mesh if (sparse_remap) for (size_t i = 0; i < result_count; ++i) From 491c7d50d24a00814a6e088314e169b24491fe54 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 12 Jul 2024 11:02:52 -0700 Subject: [PATCH 155/581] demo: Add a variant of simplifyAttr test with skipped attribute The construction of inputs to this test actually only requires one of the attributes to be present, as the middle edge of the mesh has a gradient shift on any of them, so this doesn't change the simplification behavior but will help make sure a future optimization preserves the behavior here. Also change processDev to call simplifyAttr for mesh testing. --- demo/main.cpp | 3 +-- demo/tests.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index f93bf34e86..6f956fe47d 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -1303,8 +1303,7 @@ void processDev(const char* path) if (!loadMesh(mesh, path)) return; - simplify(mesh); - simplifyClusters(mesh); + simplifyAttr(mesh); } int main(int argc, char** argv) diff --git a/demo/tests.cpp b/demo/tests.cpp index 83e2b25a64..c24e25efaf 100644 --- a/demo/tests.cpp +++ b/demo/tests.cpp @@ -1136,7 +1136,7 @@ static void simplifyLockBorder() assert(memcmp(ib, expected, sizeof(expected)) == 0); } -static void simplifyAttr() +static void simplifyAttr(bool skip_g) { float vb[8 * 3][6]; @@ -1173,7 +1173,7 @@ static void simplifyAttr() } } - float attr_weights[3] = {0.01f, 0.01f, 0.01f}; + float attr_weights[3] = {0.01f, skip_g ? 0.f : 0.01f, 0.01f}; unsigned int expected[3][6] = { {0, 2, 9, 9, 2, 11}, @@ -1551,7 +1551,8 @@ void runTests() simplifyScale(); simplifyDegenerate(); simplifyLockBorder(); - simplifyAttr(); + simplifyAttr(/* skip_g= */ false); + simplifyAttr(/* skip_g= */ true); simplifyLockFlags(); simplifySparse(); simplifyErrorAbsolute(); From 1e141fa5669baf99f64ff6eade70571b34dc7a86 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 12 Jul 2024 11:12:22 -0700 Subject: [PATCH 156/581] simplify: Only allocate and compute quadrics for used attributes If some input attributes have weight=0, we allocate and compute quadrics for those regardless of the fact that we do not need this attribute. This makes simplification more expensive when used with many attributes some of which are disabled via weight=0, requiring the caller to restructure the input data for optimal processing. With this change, we remap attributes during rescaling and recompute attribute_count to make this easier. In the future we could also detect attributes that are constant across the entire mesh, as these also should not be necessary to take into account. --- src/simplifier.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index d19e25fd5c..8fc5f2b92b 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -503,7 +503,7 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat return extent; } -static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* sparse_remap) +static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* attribute_remap, const unsigned int* sparse_remap) { size_t vertex_attributes_stride_float = vertex_attributes_stride / sizeof(float); @@ -513,9 +513,10 @@ static void rescaleAttributes(float* result, const float* vertex_attributes_data for (size_t k = 0; k < attribute_count; ++k) { - float a = vertex_attributes_data[ri * vertex_attributes_stride_float + k]; + unsigned int rk = attribute_remap[k]; + float a = vertex_attributes_data[ri * vertex_attributes_stride_float + rk]; - result[i * attribute_count + k] = a * attribute_weights[k]; + result[i * attribute_count + k] = a * attribute_weights[rk]; } } } @@ -1615,8 +1616,17 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic if (attribute_count) { + unsigned int attribute_remap[kMaxAttributes]; + + // remap attributes to only include ones with weight > 0 to minimize memory/compute overhead for quadrics + size_t attributes_used = 0; + for (size_t i = 0; i < attribute_count; ++i) + if (attribute_weights[i] > 0) + attribute_remap[attributes_used++] = unsigned(i); + + attribute_count = attributes_used; vertex_attributes = allocator.allocate(vertex_count * attribute_count); - rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count, sparse_remap); + rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count, attribute_remap, sparse_remap); } Quadric* vertex_quadrics = allocator.allocate(vertex_count); From f50fde575c066f24a5357624df568a7ccf4a9ee0 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 12 Jul 2024 11:15:34 -0700 Subject: [PATCH 157/581] simplify: Increase maximum number of attributes to 32 Generally speaking 16 is plenty, but there are some cases where it's not quite enough and having some room would be good for experimentation. --- src/meshoptimizer.h | 2 +- src/simplifier.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index 8b2345263d..76ce9d360e 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -362,7 +362,7 @@ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsig * * vertex_attributes should have attribute_count floats for each vertex * attribute_weights should have attribute_count floats in total; the weights determine relative priority of attributes between each other and wrt position. The recommended weight range is [1e-3..1e-1], assuming attribute data is in [0..1] range. - * attribute_count must be <= 16 + * attribute_count must be <= 32 * vertex_lock can be NULL; when it's not NULL, it should have a value for each vertex; 1 denotes vertices that can't be moved * TODO target_error/result_error currently use combined distance+attribute error; this may change in the future */ diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 8fc5f2b92b..eb910b2ee6 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -521,7 +521,7 @@ static void rescaleAttributes(float* result, const float* vertex_attributes_data } } -static const size_t kMaxAttributes = 16; +static const size_t kMaxAttributes = 32; struct Quadric { From b9d18eddebdf3e081edc2249437c4e5898fbf524 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 12 Jul 2024 11:28:54 -0700 Subject: [PATCH 158/581] js: Update simplifier Wasm and calling code to allow max 32 attributes Also assert that weights are non-negative. --- js/meshopt_simplifier.js | 7 +++++-- js/meshopt_simplifier.module.js | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/js/meshopt_simplifier.js b/js/meshopt_simplifier.js index 25c378bcd1..42fbd32d88 100644 --- a/js/meshopt_simplifier.js +++ b/js/meshopt_simplifier.js @@ -4,7 +4,7 @@ var MeshoptSimplifier = (function() { "use strict"; // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; // embed! wasm + var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq;Q97sdbk:C9ti8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgEBdbasazcwVg8JBd2aEaialavaHz:djjjbh8PdndnaDmbcbhvcbh3xekcbh3awhecbhCindnaeIdbJbbbb9ETmbasc;Wbfa3cdtfaCBdba3cefh3kaeclfheaDaCcefgC9hmbkascxfa8Jcdtfcua3al2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmba3Tmbarcd4hKdnaHTmba3cdthicbhQavhYinaoaHaQcdtfydbaK2cdtfhLasc;WbfheaYhCa3hXinaCaLaeydbcdtg8AfIdbawa8AfIdbNUdbaeclfheaCclfhCaXcufgXmbkaYaifhYaQcefgQal9hmbxdkka3cdthicbhQavhYinaoaQaK2cdtfhLasc;WbfheaYhCa3hXinaCaLaeydbcdtg8AfIdbawa8AfIdbNUdbaeclfheaCclfhCaXcufgXmbkaYaifhYaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8Kdndndna3Tmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcua3al2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgzBdbasa8JcifBd2azcbaCz:ljjjb8AadmexdkcbhqcbhzadTmekcbhLabhCindnaEaCclfydbgQcx2fgeIdbaEaCydbgYcx2fgXIdbgI:tg8RaEaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnaEaXcx2fgKIdwaEa8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnaEaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbka3TmbcbhYinJbbbbh8XaEabaYcdtfgeclfydbgKcx2fgCIdwaEaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80aEaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaia32cdtfhCava8Ja32cdtfhXavaKa32cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLa3hQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyazaCa32cltfhQcbhCa3h8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkazaKa32cltfhQcbhCa3h8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8Ambkazaia32cltfhQcbhCa3h8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgoBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbggBdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBa3clthTahcwfhSJbbbbh83inasclfabadgDalaOz:cjjjbabhicbhdcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgwaQcv2aYfg5c;a1jjbfRbbgaVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahadcx2fg8AaCaXaacFeGgLEBdla8AaXaCaLEBdba8AaLawGcb9hBdwadcefhdkaeclfgecx9hmbkdnaycifgyaD9pmbaicxfhiadcifa8L9nmekkdnadmbaDhdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgwc8S2gafgeIdygR:vaRJbbbb9BEaeIdwaEaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwaEaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dna3TmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLa32cdtfhCazaya32cltfheaXIdyh8Ya3hXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqaafgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKa32cdtfhCazawa32cltfheaXIdyh8Xa3hXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYad9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheadhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbaoaXcdtfaeBdbaCcxfhCadaecefge9hmbkaDak9RgXci9Uh9hdnalTmbcbheaghCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhacbh5dninahaoa5cdtfydbcx2fg8JIdwg8RaB9Emeaaa9h9pmeJFFuuhRdna0ad9pmbahaoa0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbaaa9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaEa8Acx2fgKcwfhyaKclfh8EaEa9rcx2fgwcwfhmawclfhrcbhCcehYdnindnagaeydbcdtfydbgXa8ASmbagaeclfydbcdtfydbgLa8ASmbaXaLSmbaEaLcx2fgLIdbaEaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNawIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydna3TmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKazhCa3hLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheinagaecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhiaga9qfa9nBdbaeh9nkagaicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEaafhaka5cefg5ad9hmbkkdna9imbaDhdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCagaXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCagaXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindnagaeydbcdtfydbgCagaeclfydbcdtfydbgXSmbaCagaecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLaD6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; // embed! wasm var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); @@ -214,7 +214,10 @@ var MeshoptSimplifier = (function() { assert(target_error >= 0); assert(Array.isArray(attribute_weights)); assert(vertex_attributes_stride >= attribute_weights.length); - assert(attribute_weights.length <= 16); + assert(attribute_weights.length <= 32); + for (var i = 0; i < attribute_weights.length; ++i) { + assert(attribute_weights[i] >= 0); + } var options = 0; for (var i = 0; i < (flags ? flags.length : 0); ++i) { diff --git a/js/meshopt_simplifier.module.js b/js/meshopt_simplifier.module.js index 74db1fb672..9b4a44d398 100644 --- a/js/meshopt_simplifier.module.js +++ b/js/meshopt_simplifier.module.js @@ -3,7 +3,7 @@ var MeshoptSimplifier = (function() { // Built with clang version 18.1.2 // Built from meshoptimizer 0.21 - var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq:f97sdbk:39si8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbggBdbasazcwVg8JBd2agaialavaHz:djjjbh8PdndnaDmbcbhvxekascxfa8JcdtfcualaD2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmbarcd4hYdnaHTmbaDcdthKcbhLavhQinaoaHaLcdtfydbaY2cdtfheawhCaQhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaQaKfhQaLcefgLal9hmbxdkkaYcdthYaDcdthKcbhQavhLinaoheawhCaLhXaDh8AinaXaeIdbaCIdbNUdbaeclfheaCclfhCaXclfhXa8Acufg8AmbkaoaYfhoaLaKfhLaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8KdndndnaDTmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcualaD2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgwBdbasa8JcifBd2awcbaCz:ljjjb8AadmexdkcbhqcbhwadTmekcbhLabhCindnagaCclfydbgQcx2fgeIdbagaCydbgYcx2fgXIdbgI:tg8RagaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnagaXcx2fgKIdwaga8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnagaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbkaDTmbcbhYinJbbbbh8XagabaYcdtfgeclfydbgKcx2fgCIdwagaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80agaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaiaD2cdtfhCava8JaD2cdtfhXavaKaD2cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLaDhQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyawaCaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaKaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkawaiaD2cltfhQcbhCaDh8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgzBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbg3BdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBaDclthTahcwfhSJbbbbh83inasclfabadgoalaOz:cjjjbabhicbhEcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgaaQcv2aYfg5c;a1jjbfRbbgdVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahaEcx2fg8AaCaXadcFeGgLEBdla8AaXaCaLEBdba8AaLaaGcb9hBdwaEcefhEkaeclfgecx9hmbkdnaycifgyao9pmbaicxfhiaEcifa8L9nmekkdnaEmbaohdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgac8S2gdfgeIdygR:vaRJbbbb9BEaeIdwagaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwagaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dnaDTmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLaD2cdtfhCawayaD2cltfheaXIdyh8YaDhXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqadfgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKaD2cdtfhCawaaaD2cltfheaXIdyh8XaDhXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYaE9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheaEhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbazaXcdtfaeBdbaCcxfhCaEaecefge9hmbkaoak9RgXci9Uh9hdnalTmbcbhea3hCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhdcbh5dninahaza5cdtfydbcx2fg8JIdwg8RaB9Emeada9h9pmeJFFuuhRdna0aE9pmbahaza0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbada9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaga8Acx2fgKcwfhyaKclfh8Eaga9rcx2fgacwfhmaaclfhrcbhCcehYdnindna3aeydbcdtfydbgXa8ASmba3aeclfydbcdtfydbgLa8ASmbaXaLSmbagaLcx2fgLIdbagaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNaaIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydnaDTmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKawhCaDhLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheina3aecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhia3a9qfa9nBdbaeh9nka3aicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEadfhdka5cefg5aE9hmbkkdna9imbaohdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCa3aXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindna3aeydbcdtfydbgCa3aeclfydbcdtfydbgXSmbaCa3aecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLao6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; // embed! wasm + var wasm = "b9H79Tebbbe9Hk9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gvuuuuue999Gquuuuuuu99uueu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9GiuuueuizsdilvoirwDbqqbeqlve9Weiiviebeoweuecj;jekr:Tewo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bl8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bvQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7boX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2Wbra9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbwl79IV9RbDDwebcekdmxq;Q97sdbk:C9ti8Au8A99zu8Jjjjjbc;W;ab9Rgs8Kjjjjbcbhzascxfcbc;Kbz:ljjjb8AdnabaeSmbabaeadcdtz:kjjjb8AkdndnamcdGmbcbhHxekasalcrfci4gecbyd;S1jjbHjjjjbbgOBdxasceBd2aOcbaez:ljjjbhAcbhlcbhednadTmbcbhlabheadhOinaAaeydbgCci4fgXaXRbbgXceaCcrGgCtV86bbaXcu7aC4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekasaecbyd;S1jjbHjjjjbbgHBdzascdBd2alcd4alfhCcehOinaOgecethOaeaC6mbkcdhzcbhQascuaecdtgOaecFFFFi0Ecbyd;S1jjbHjjjjbbgCBdCasciBd2aCcFeaOz:ljjjbhLdnadTmbaecufhXcbhKinabaQcdtfgYydbgAc:v;t;h;Ev2hCcbhedndninaLaCaXGgCcdtfg8AydbgOcuSmeaHaOcdtfydbaASmdaecefgeaCfhCaeaX9nmbxdkkaHaKcdtfaABdba8AaKBdbaKhOaKcefhKkaYaOBdbaQcefgQad9hmbkkaLcbyd;O1jjbH:bjjjbbascdBd2kascxfazcdtfcualcefgecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgEBdbasaEBdlasazceVgeBd2ascxfaecdtfcuadcitadcFFFFe0Ecbyd;S1jjbHjjjjbbg3Bdbasa3BdwasazcdfgeBd2asclfabadalcbz:cjjjbascxfaecdtfcualcdtg5alcFFFFi0Eg8Ecbyd;S1jjbHjjjjbbgOBdbasazcifgeBd2ascxfaecdtfa8Ecbyd;S1jjbHjjjjbbg8FBdbasazclVgaBd2alcd4alfhXcehCinaCgecethCaeaX6mbkcbhKascxfaacdtfghcuaecdtgCaecFFFFi0Ecbyd;S1jjbHjjjjbbgXBdbasazcvVggBd2aXcFeaCz:ljjjbhQdnalTmbavcd4hAaecufhCinaKhednaHTmbaHaKcdtfydbhekaiaeaA2cdtfgeydlgXcH4aX7c:F:b:DD2aeydbgXcH4aX7c;D;O:B8J27aeydwgecH4ae7c:3F;N8N27aCGheaKcdth8JdndndndndnaHTmbaHa8JfhYcbhXinaQaecdtfgLydbg8AcuSmlaiaHa8AcdtfydbaA2cdtfaiaYydbaA2cdtfcxz:ojjjbTmiaXcefgXaefaCGheaXaC9nmbxdkkaiaKaA2cdtfhYcbhXinaQaecdtfgLydbg8AcuSmiaia8AaA2cdtfaYcxz:ojjjbTmdaXcefgXaefaCGheaXaC9nmbkkcbhLkaLydbgecu9hmekaLaKBdbaKhekaOa8JfaeBdbaKcefgKal9hmbkcbhea8FhCinaCaeBdbaCclfhCalaecefge9hmbkcbheaOhCa8FhXindnaeaCydbgASmbaXa8FaAcdtfgAydbBdbaAaeBdbkaCclfhCaXclfhXalaecefge9hmbkkcbh8KaQcbyd;O1jjbH:bjjjbbasaaBd2ahalcbyd;S1jjbHjjjjbbgABdbasagBd2ascxfagcdtfa8Ecbyd;S1jjbHjjjjbbgeBdbasazcofgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbgCBdbasazcrfg8LBd2aecFea5z:ljjjbh8MaCcFea5z:ljjjbh8NdnalTmba3cwfhyindnaEa8KgXcefg8Kcdtfydbg8AaEaXcdtgefydbgCSmba8AaC9Rh8Ja3aCcitfh5a8Naefhga8MaefhKcbhLindndna5aLcitfydbgQaX9hmbaKaXBdbagaXBdbxekdnaEaQcdtgafgeclfydbgCaeydbgeSmba3aecitg8AfydbaXSmeaCae9Rhhaecu7aCfhYaya8AfhCcbheinaYaeSmeaecefheaCydbh8AaCcwfhCa8AaX9hmbkaeah6meka8NaafgeaXaQaeydbcuSEBdbaKaQaXaKydbcuSEBdbkaLcefgLa8J9hmbkka8Kal9hmbkaOhCaHhLa8FhXa8Nh8Aa8MhQcbheindndnaeaCydbgY9hmbdnaqTmbaehYdnaHTmbaLydbhYkaqaYfRbbTmbaAaefcl86bbxdkdnaeaXydbgY9hmbaQydbhYdna8AydbgKcu9hmbaYcu9hmbaAaefcb86bbxikaAaefh8JdnaeaKSmbaeaYSmba8Jce86bbxika8Jcl86bbxdkdnaea8FaYcdtgKfydb9hmbdna8Aydbg8JcuSmbaea8JSmbaQydbg5cuSmbaea5Smba8NaKfydbgacuSmbaaaYSmba8MaKfydbgKcuSmbaKaYSmbdnaOa8JcdtfydbaOaKcdtfydb9hmbaOa5cdtfydbaOaacdtfydb9hmbaAaefcd86bbxlkaAaefcl86bbxikaAaefcl86bbxdkaAaefcl86bbxekaAaefaAaYfRbb86bbkaCclfhCaLclfhLaXclfhXa8Aclfh8AaQclfhQalaecefge9hmbkamceGTmbaAhealhCindnaeRbbce9hmbaecl86bbkaecefheaCcufgCmbkkascxfa8Lcdtfcualcx2alc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgEBdbasazcwVg8JBd2aEaialavaHz:djjjbh8PdndnaDmbcbhvcbh3xekcbh3awhecbhCindnaeIdbJbbbb9ETmbasc;Wbfa3cdtfaCBdba3cefh3kaeclfheaDaCcefgC9hmbkascxfa8Jcdtfcua3al2gecdtaecFFFFi0Ecbyd;S1jjbHjjjjbbgvBdbasazcDVg8JBd2alTmba3Tmbarcd4hKdnaHTmba3cdthicbhQavhYinaoaHaQcdtfydbaK2cdtfhLasc;WbfheaYhCa3hXinaCaLaeydbcdtg8AfIdbawa8AfIdbNUdbaeclfheaCclfhCaXcufgXmbkaYaifhYaQcefgQal9hmbxdkka3cdthicbhQavhYinaoaQaK2cdtfhLasc;WbfheaYhCa3hXinaCaLaeydbcdtg8AfIdbawa8AfIdbNUdbaeclfheaCclfhCaXcufgXmbkaYaifhYaQcefgQal9hmbkkascxfa8Jcdtfcualc8S2gealc;D;O;f8U0EgXcbyd;S1jjbHjjjjbbgCBdbasa8Jcefg8ABd2aCcbaez:ljjjbh8Kdndndna3Tmbascxfa8AcdtfaXcbyd;S1jjbHjjjjbbgqBdbasa8JcdfgCBd2aqcbaez:ljjjb8AascxfaCcdtfcua3al2gecltgCaecFFFFb0Ecbyd;S1jjbHjjjjbbgzBdbasa8JcifBd2azcbaCz:ljjjb8AadmexdkcbhqcbhzadTmekcbhLabhCindnaEaCclfydbgQcx2fgeIdbaEaCydbgYcx2fgXIdbgI:tg8RaEaCcwfydbgKcx2fg8AIdlaXIdlg8S:tgRNa8AIdbaI:tg8UaeIdla8S:tg8VN:tg8Wa8WNa8Va8AIdwaXIdwg8X:tg8YNaRaeIdwa8X:tg8VN:tgRaRNa8Va8UNa8Ya8RN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOaYcdtfydbc8S2fgeaRa8U:rg8UaRNNg8VaeIdbMUdbaea8Ra8Ua8RNg8ZNg8YaeIdlMUdlaea8Wa8Ua8WNg80Ng81aeIdwMUdwaea8ZaRNg8ZaeIdxMUdxaea80aRNgBaeIdzMUdzaea80a8RNg80aeIdCMUdCaeaRa8Ua8Wa8XNaRaINa8Sa8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaQcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaKcdtfydbc8S2fgea8VaeIdbMUdbaea8YaeIdlMUdlaea81aeIdwMUdwaea8ZaeIdxMUdxaeaBaeIdzMUdzaea80aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdyaCcxfhCaLcifgLad6mbkcbh8JabhYinaba8JcdtfhQcbhCinaAaQaCcj1jjbfydbcdtfydbgXfRbbhedndnaAaYaCfydbg8AfRbbgLc99fcFeGcpe0mbaeceSmbaecd9hmekdnaLcufcFeGce0mba8Ma8AcdtfydbaX9hmekdnaecufcFeGce0mba8NaXcdtfydba8A9hmekdnaLcv2aefc:q1jjbfRbbTmbaOaXcdtfydbaOa8Acdtfydb0mekdnaEaXcx2fgKIdwaEa8Acx2fgiIdwg8S:tgRaRNaKIdbaiIdbg8X:tg8Ra8RNaKIdlaiIdlg8V:tg8Ua8UNMM:rgIJbbbb9ETmbaRaI:vhRa8UaI:vh8Ua8RaI:vh8RkJbbacJbbacJbbjZaeceSEaLceSEh80dnaEaQaCc:e1jjbfydbcdtfydbcx2fgeIdwa8S:tg8WaRa8WaRNaeIdba8X:tg81a8RNa8UaeIdla8V:tg8ZNMMg8YN:tg8Wa8WNa81a8Ra8YN:tgRaRNa8Za8Ua8YN:tg8Ra8RNMM:rg8UJbbbb9ETmba8Wa8U:vh8Wa8Ra8U:vh8RaRa8U:vhRka8KaOa8Acdtfydbc8S2fgeaRa80aINg8UaRNNg8YaeIdbMUdbaea8Ra8Ua8RNg80Ng81aeIdlMUdlaea8Wa8Ua8WNgINg8ZaeIdwMUdwaea80aRNg80aeIdxMUdxaeaIaRNgBaeIdzMUdzaeaIa8RNg83aeIdCMUdCaeaRa8Ua8Wa8SNaRa8XNa8Va8RNMM:mg8SNgINgRaeIdKMUdKaea8RaINg8RaeId3MUd3aea8WaINg8WaeIdaMUdaaeaIa8SNgIaeId8KMUd8Kaea8UaeIdyMUdya8KaOaXcdtfydbc8S2fgea8YaeIdbMUdbaea81aeIdlMUdlaea8ZaeIdwMUdwaea80aeIdxMUdxaeaBaeIdzMUdzaea83aeIdCMUdCaeaRaeIdKMUdKaea8RaeId3MUd3aea8WaeIdaMUdaaeaIaeId8KMUd8Kaea8UaeIdyMUdykaCclfgCcx9hmbkaYcxfhYa8Jcifg8Jad6mbka3TmbcbhYinJbbbbh8XaEabaYcdtfgeclfydbgKcx2fgCIdwaEaeydbgicx2fgXIdwg8Z:tg8Ra8RNaCIdbaXIdbgB:tg8Wa8WNaCIdlaXIdlg83:tg8Ua8UNMMg80aEaecwfydbg8Jcx2fgeIdwa8Z:tgINa8Ra8RaINa8WaeIdbaB:tg8SNa8UaeIdla83:tg8VNMMgRN:tJbbbbJbbjZa80aIaINa8Sa8SNa8Va8VNMMg81NaRaRN:tg8Y:va8YJbbbb9BEg8YNhUa81a8RNaIaRN:ta8YNh85a80a8VNa8UaRN:ta8YNh86a81a8UNa8VaRN:ta8YNh87a80a8SNa8WaRN:ta8YNh88a81a8WNa8SaRN:ta8YNh89a8Wa8VNa8Sa8UN:tgRaRNa8UaINa8Va8RN:tgRaRNa8Ra8SNaIa8WN:tgRaRNMM:r:rhRavaia32cdtfhCava8Ja32cdtfhXavaKa32cdtfh8Aa8Z:mh8:a83:mhZaB:mhncbhLa3hQJbbbbh8VJbbbbh8YJbbbbh80Jbbbbh81Jbbbbh8ZJbbbbhBJbbbbh83JbbbbhcJbbbbh9cinasc;WbfaLfgecwfaRa85a8AIdbaCIdbgI:tg8UNaUaXIdbaI:tg8SNMg8RNUdbaeclfaRa87a8UNa86a8SNMg8WNUdbaeaRa89a8UNa88a8SNMg8UNUdbaecxfaRa8:a8RNaZa8WNaIana8UNMMMgINUdbaRa8Ra8WNNa81Mh81aRa8Ra8UNNa8ZMh8ZaRa8Wa8UNNaBMhBaRaIaINNa8XMh8XaRa8RaINNa8VMh8VaRa8WaINNa8YMh8YaRa8UaINNa80Mh80aRa8Ra8RNNa83Mh83aRa8Wa8WNNacMhcaRa8Ua8UNNa9cMh9caCclfhCa8Aclfh8AaXclfhXaLczfhLaQcufgQmbkaqaOaicdtfydbgCc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOaKcdtfydbgKc8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyaqaOa8Jcdtfydbgic8S2fgea9caeIdbMUdbaeacaeIdlMUdlaea83aeIdwMUdwaeaBaeIdxMUdxaea8ZaeIdzMUdzaea81aeIdCMUdCaea80aeIdKMUdKaea8YaeId3MUd3aea8VaeIdaMUdaaea8XaeId8KMUd8KaeaRaeIdyMUdyazaCa32cltfhQcbhCa3h8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkazaKa32cltfhQcbhCa3h8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8Ambkazaia32cltfhQcbhCa3h8AinaQaCfgeasc;WbfaCfgXIdbaeIdbMUdbaeclfgLaXclfIdbaLIdbMUdbaecwfgLaXcwfIdbaLIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCa8Acufg8AmbkaYcifgYad6mbkkasydlhJcbhednalTmbaJclfheaJydbh8AaAhCalhLcbhXincbaeydbgQa8A9RaCRbbcpeGEaXfhXaCcefhCaeclfheaQh8AaLcufgLmbkaXce4hekcuadae9Rcifg8Lcx2a8Lc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbhhascxfasyd2gecdtfahBdbasaecefgCBd2ascxfaCcdtfcua8Lcdta8LcFFFFi0Ecbyd;S1jjbHjjjjbbgoBdbasaecdfgCBd2ascxfaCcdtfa8Ecbyd;S1jjbHjjjjbbggBdbasaecifgCBd2ascxfaCcdtfalcbyd;S1jjbHjjjjbbg9eBdbasaeclfBd2a8PJbbjZamclGEhcJbbbbh83dnadak9nmbdna8Lci6mbaxaxNacacN:vhBa3clthTahcwfhSJbbbbh83inasclfabadgDalaOz:cjjjbabhicbhdcbhyinabaycdtfh8JcbheindnaOaiaefydbgXcdtgKfydbg8AaOa8Jaec:S1jjbfydbcdtfydbgCcdtfydbgLSmbaAaCfRbbgYcv2aAaXfRbbgQfc;a1jjbfRbbgwaQcv2aYfg5c;a1jjbfRbbgaVcFeGTmbdnaLa8A9nmba5c:q1jjbfRbbcFeGmekdnaQaY9hmbaQcufcFeGce0mba8MaKfydbaC9hmekahadcx2fg8AaCaXaacFeGgLEBdla8AaXaCaLEBdba8AaLawGcb9hBdwadcefhdkaeclfgecx9hmbkdnaycifgyaD9pmbaicxfhiadcifa8L9nmekkdnadmbaDhdxikcbhYinJbbbbJbbjZa8KaOahaYcx2fg8AydlgLa8AydbgQa8AydwgCEgicdtfydbgwc8S2gafgeIdygR:vaRJbbbb9BEaeIdwaEaQaLaCEgKcx2fgCIdwg8UNaeIdzaCIdbgINaeIdaMgRaRMMa8UNaeIdlaCIdlg8SNaeIdCa8UNaeId3MgRaRMMa8SNaeIdbaINaeIdxa8SNaeIdKMgRaRMMaINaeId8KMMM:lNh80JbbbbJbbjZa8KaOaQcdtfydbgyc8S2gXfgeIdygR:vaRJbbbb9BEaeIdwaEaLcx2fgCIdwg8WNaeIdzaCIdbg8XNaeIdaMgRaRMMa8WNaeIdlaCIdlg8VNaeIdCa8WNaeId3MgRaRMMa8VNaeIdba8XNaeIdxa8VNaeIdKMgRaRMMa8XNaeId8KMMM:lNh81a8Acwfh8Ja8Aclfh5dna3TmbaqaXfgXIdwa8WNaXIdza8XNaXIdaMgRaRMMa8WNaXIdla8VNaXIdCa8WNaXId3MgRaRMMa8VNaXIdba8XNaXIdxa8VNaXIdKMgRaRMMa8XNaXId8KMMMh8RavaLa32cdtfhCazaya32cltfheaXIdyh8Ya3hXinaCIdbgRJbbb;aNaecxfIdba8WaecwfIdbNa8XaeIdbNa8VaeclfIdbNMMMNaRaRNa8YNa8RMMh8RaCclfhCaeczfheaXcufgXmbkaqaafgXIdwa8UNaXIdzaINaXIdaMgRaRMMa8UNaXIdla8SNaXIdCa8UNaXId3MgRaRMMa8SNaXIdbaINaXIdxa8SNaXIdKMgRaRMMaINaXId8KMMMh8WavaKa32cdtfhCazawa32cltfheaXIdyh8Xa3hXinaCIdbgRJbbb;aNaecxfIdba8UaecwfIdbNaIaeIdbNa8SaeclfIdbNMMMNaRaRNa8XNa8WMMh8WaCclfhCaeczfheaXcufgXmbka80a8W:lMh80a81a8R:lMh81ka5aLaKa81a809FgeEBdba8AaQaiaeEBdba8Ja81a80aeEUdbaYcefgYad9hmbkasc;Wbfcbcj;abz:ljjjb8AaSheadhCinasc;WbfaeydbcO4c;8ZGfgXaXydbcefBdbaecxfheaCcufgCmbkcbhecbhCinasc;WbfaefgXydbh8AaXaCBdba8AaCfhCaeclfgecj;ab9hmbkcbheaShCinasc;WbfaCydbcO4c;8ZGfgXaXydbgXcefBdbaoaXcdtfaeBdbaCcxfhCadaecefge9hmbkaDak9RgXci9Uh9hdnalTmbcbheaghCinaCaeBdbaCclfhCalaecefge9hmbkkcbh9ia9ecbalz:ljjjbh6aXcO9Uh9ka9hce4h0asydwh9mcbhacbh5dninahaoa5cdtfydbcx2fg8JIdwg8RaB9Emeaaa9h9pmeJFFuuhRdna0ad9pmbahaoa0cdtfydbcx2fIdwJbb;aZNhRkdna8RaR9ETmbaaa9k0mdkdna6aOa8Jydlg9ncdtg9ofydbg8Afg9pRbba6aOa8Jydbgicdtg9qfydbg9rfg9sRbbVmbdnaJa9rcdtfgeclfydbgCaeydbgeSmbaCae9RhQa9maecitfheaEa8Acx2fgKcwfhyaKclfh8EaEa9rcx2fgwcwfhmawclfhrcbhCcehYdnindnagaeydbcdtfydbgXa8ASmbagaeclfydbcdtfydbgLa8ASmbaXaLSmbaEaLcx2fgLIdbaEaXcx2fgXIdbg8W:tgRarIdbaXIdlg8U:tg8XNawIdba8W:tg8VaLIdla8U:tg8RN:tgIaRa8EIdba8U:tg8YNaKIdba8W:tg80a8RN:tg8UNa8RamIdbaXIdwg8S:tg81Na8XaLIdwa8S:tg8WN:tg8Xa8RayIdba8S:tg8ZNa8Ya8WN:tg8RNa8Wa8VNa81aRN:tg8Sa8Wa80Na8ZaRN:tgRNMMaIaINa8Xa8XNa8Sa8SNMMa8Ua8UNa8Ra8RNaRaRNMMN:rJbbj8:N9FmdkaecwfheaCcefgCaQ6hYaQaC9hmbkkaYceGTmba0cefh0xeka8Ka8Ac8S2gXfgea8Ka9rc8S2gLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdydna3TmbaqaXfgeaqaLfgCIdbaeIdbMUdbaeaCIdlaeIdlMUdlaeaCIdwaeIdwMUdwaeaCIdxaeIdxMUdxaeaCIdzaeIdzMUdzaeaCIdCaeIdCMUdCaeaCIdKaeIdKMUdKaeaCId3aeId3MUd3aeaCIdaaeIdaMUdaaeaCId8KaeId8KMUd8KaeaCIdyaeIdyMUdyaTa9r2hYaTa8A2hKazhCa3hLinaCaKfgeaCaYfgXIdbaeIdbMUdbaeclfgQaXclfIdbaQIdbMUdbaecwfgQaXcwfIdbaQIdbMUdbaecxfgeaXcxfIdbaeIdbMUdbaCczfhCaLcufgLmbkka8JcwfhCdndndndnaAaifgXRbbc9:fPdebdkaiheinagaecdtgefa8ABdba8Faefydbgeai9hmbxikka8Fa9ofydbhea8Fa9qfydbhiaga9qfa9nBdbaeh9nkagaicdtfa9nBdbka9sce86bba9pce86bbaCIdbgRa83a83aR9DEh83a9icefh9icecdaXRbbceSEaafhaka5cefg5ad9hmbkkdna9imbaDhdxikdnalTmbcbhCa8MheindnaeydbgXcuSmbdnaCagaXcdtg8AfydbgX9hmba8Ma8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkcbhCa8NheindnaeydbgXcuSmbdnaCagaXcdtg8AfydbgX9hmba8Na8AfydbhXkaeaXBdbkaeclfhealaCcefgC9hmbkkcbhdabhecbhLindnagaeydbcdtfydbgCagaeclfydbcdtfydbgXSmbaCagaecwfydbcdtfydbg8ASmbaXa8ASmbabadcdtfgQaCBdbaQcwfa8ABdbaQclfaXBdbadcifhdkaecxfheaLcifgLaD6mbkadak9nmdxbkkasclfabadalaOz:cjjjbkdnaHTmbadTmbadheinabaHabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPaca83:rNUdbkasyd2gecdtascxffc98fhOdninaeTmeaOydbcbyd;O1jjbH:bjjjbbaOc98fhOaecufhexbkkasc;W;abf8Kjjjjbadk;Yieouabydlhvabydbclfcbaicdtz:ljjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk;Podvuv998Jjjjjbca9RgvcFFF;7rBd3av9cFFF;7;3FF:;Fb83dCavcFFF97Bdzav9cFFF;7FFF:;u83dwdnadTmbaicd4hodnabmbdnalTmbcbhrinaealarcdtfydbao2cdtfhwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxikkaocdthrcbhwincbhiinavcCfaifgDaeaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkaearfheawcefgwad9hmbxdkkdnalTmbcbhrinabarcx2fgiaealarcdtfydbao2cdtfgwIdbUdbaiawIdlUdlaiawIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkarcefgrad9hmbxdkkaocdthlcbhraehwinabarcx2fgiaearao2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinavcCfaifgDawaifIdbgqaDIdbgkakaq9EEUdbavcwfaifgDaqaDIdbgkakaq9DEUdbaiclfgicx9hmbkawalfhwarcefgrad9hmbkkJbbbbavIdwavIdCgk:tgqaqJbbbb9DEgqavIdxavIdKgx:tgmamaq9DEgqavIdzavId3gm:tgPaPaq9DEhPdnabTmbadTmbJbbbbJbbjZaP:vaPJbbbb9BEhqinabaqabIdbak:tNUdbabclfgvaqavIdbax:tNUdbabcwfgvaqavIdbam:tNUdbabcxfhbadcufgdmbkkaPk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbk;3Aowud99wue99iul998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:ljjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd;S1jjbHjjjjbbgqBdxawceBd2aqaeadaicbz:djjjb8AawcuadcdtadcFFFFi0Egkcbyd;S1jjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhmawcuaicdtgPaicFFFFi0Ecbyd;S1jjbHjjjjbbgsBdCawciBd2dndnar:Zgz:rJbbbZMgH:lJbbb9p9DTmbaH:Ohexekcjjjj94hekaicufhOc:bwhAcbhCcbhXadhQinaChLaeaAgKcufaeaK9iEamgDcefaeaD9kEhYdndnadTmbaYcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbh3cbh5indnaEaxa5cdtfydbgAcm4aA7c:v;t;h;Ev2gics4ai7aOGgmcdtfgCydbgecuSmbaeaASmbcehiinaEamaifaOGgmcdtfgCydbgecuSmeaicefhiaeaA9hmbkkaCaABdba3aecuSfh3a5cefg5ad9hmbxdkkascFeaPz:ljjjb8Acbh3kaDaYa3ar0giEhmaLa3aiEhCdna3arSmbaYaKaiEgAam9Rcd9imbdndnaXcl0mbdnaQ:ZgHaL:Zg8A:taY:Yg8EaD:Y:tg8Fa8EaK:Y:tgaa3:Zghaz:tNNNaHaz:taaNa8Aah:tNa8Aaz:ta8FNahaH:tNM:va8EMJbbbZMgH:lJbbb9p9DTmbaH:Ohexdkcjjjj94hexekamaAfcd9Theka3aQaiEhQaXcefgXcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd;S1jjbHjjjjbbg5BdKawclBd2dndnadTmbamcuf:YhHaqhiaxheadhmindndnaiIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhAxekcjjjj94hAkaAcCthAdndnaiclfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaCcqtaAVhAdndnaicwfIdbaHNJbbbZMg8A:lJbbb9p9DTmba8A:OhCxekcjjjj94hCkaeaAaCVBdbaicxfhiaeclfheamcufgmmbkascFeaPz:ljjjbhEcbhDcbh3inaxa3cdtgYfydbgAcm4aA7c:v;t;h;Ev2gics4ai7hecbhidndninaEaeaOGgmcdtfgCydbgecuSmednaxaecdtgCfydbaASmbaicefgiamfheaiaO9nmekka5aCfydbhixekaCa3BdbaDhiaDcefhDka5aYfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekascFeaPz:ljjjb8AcbhDcbhekawaecbyd;S1jjbHjjjjbbgeBd3awcvBd2aecbaiz:ljjjbhCavcd4hxdnadTmbdnalTmbaxcdthEa5hAalheaqhmadhOinaCaAydbc32fgiamIdbaiIdbMUdbaiamclfIdbaiIdlMUdlaiamcwfIdbaiIdwMUdwaiaeIdbaiIdxMUdxaiaeclfIdbaiIdzMUdzaiaecwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaAclfhAaeaEfheamcxfhmaOcufgOmbxdkka5hmaqheadhAinaCamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaAcufgAmbkkdnaDTmbaChiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgH:vaHJbbbb9BEgHNUdbaiclfgmaHamIdbNUdbaicwfgmaHamIdbNUdbaicxfgmaHamIdbNUdbaiczfgmaHamIdbNUdbaicCfgmaHamIdbNUdbaic3fhiaecufgembkkcbhAawcuaDcdtgYaDcFFFFi0Egicbyd;S1jjbHjjjjbbgeBdaawcoBd2awaicbyd;S1jjbHjjjjbbgEBd8KaecFeaYz:ljjjbh3dnadTmbaoaoNh8Aaxcdthxalheina8Aaec;C1jjbalEgmIdwaCa5ydbgOc32fgiIdC:tgHaHNamIdbaiIdx:tgHaHNamIdlaiIdz:tgHaHNMMNaqcwfIdbaiIdw:tgHaHNaqIdbaiIdb:tgHaHNaqclfIdbaiIdl:tgHaHNMMMhHdndna3aOcdtgifgmydbcuSmbaEaifIdbaH9ETmekamaABdbaEaifaHUdbka5clfh5aeaxfheaqcxfhqadaAcefgA9hmbkkaba3aYz:kjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd;O1jjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Odieui99iu8Jjjjjbca9RgicFFF;7rBd3ai9cFFF;7;3FF:;Fb83dCaicFFF97Bdzai9cFFF;7FFF:;u83dwdndnaembJbbjFhlJbbjFhvJbbjFhoxekadcd4cdthrcbhwincbhdinaicCfadfgDabadfIdbglaDIdbgvaval9EEUdbaicwfadfgDalaDIdbgvaval9DEUdbadclfgdcx9hmbkabarfhbawcefgwae9hmbkaiIdzaiId3:thoaiIdxaiIdK:thvaiIdwaiIdC:thlkJbbbbalalJbbbb9DEglavaval9DEglaoaoal9DEk9DeeuabcFeaicdtz:ljjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcifc98GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd;W1jjbgeabcrfc94GfgbBd;W1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik9:eiuZbhedndncbyd;W1jjbgdaecztgi9nmbcuheadai9RcFFifcz4nbcuSmekadhekcbabae9Rcifc98Gcbyd;W1jjbfgdBd;W1jjbdnadZbcztge9nmbadae9RcFFifcz4nb8Akk6eiucbhidnadTmbdninabRbbglaeRbbgv9hmeaecefheabcefhbadcufgdmbxdkkalav9Rhikaikk:bedbcjwk9Oebbbdbbbbbbbebbbeeebeebebbeeebebbbbbebebbbbbebbbdbbbbbbbbbbbbbbbeeeeebebbbbbebbbbbeebbbbbbbbbbbbbbbbbbbbbc;Owkxebbbdbbbj9Kbb"; // embed! wasm var wasmpack = new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]); @@ -213,7 +213,10 @@ var MeshoptSimplifier = (function() { assert(target_error >= 0); assert(Array.isArray(attribute_weights)); assert(vertex_attributes_stride >= attribute_weights.length); - assert(attribute_weights.length <= 16); + assert(attribute_weights.length <= 32); + for (var i = 0; i < attribute_weights.length; ++i) { + assert(attribute_weights[i] >= 0); + } var options = 0; for (var i = 0; i < (flags ? flags.length : 0); ++i) { From e3f97f216d1881657aaf781603b91d1fe5625ae7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 12 Jul 2024 11:33:08 -0700 Subject: [PATCH 159/581] simplify: Assert that target error and weights are non-negative Target error is squared during processing so negative values will behave oddly in addition to being non-sensical; negative attribute weights are currently benign but may lead to odd issues in the future, and we now skip attributes with weight <= 0 so negative weight is clearly an error. --- src/simplifier.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index eb910b2ee6..34c4490a9c 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -1561,10 +1561,13 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(target_index_count <= index_count); + assert(target_error >= 0); assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute | meshopt_SimplifyInternalDebug)) == 0); assert(vertex_attributes_stride >= attribute_count * sizeof(float) && vertex_attributes_stride <= 256); assert(vertex_attributes_stride % sizeof(float) == 0); assert(attribute_count <= kMaxAttributes); + for (size_t i = 0; i < attribute_count; ++i) + assert(attribute_weights[i] >= 0); meshopt_Allocator allocator; From 92c22ab3bfd4b11124ada1c0bb8e3af10e1d5582 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 22 Jul 2024 08:55:25 -0700 Subject: [PATCH 160/581] gltfpack: Do not merge mesh primitives with different scenes This results in some meshes migrating between scenes in case they were detached from their existing nodes. --- gltf/gltfpack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index e6afb21cd0..85c6ad0b92 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -560,7 +560,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output { const Mesh& prim = meshes[pi]; - if (prim.skin != mesh.skin || prim.targets != mesh.targets) + if (prim.scene != mesh.scene || prim.skin != mesh.skin || prim.targets != mesh.targets) break; if (pi > i && (mesh.instances.size() || prim.instances.size())) From 3fa2e91660b0998cb40264904c325cdb106fd221 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 22 Jul 2024 10:39:47 -0700 Subject: [PATCH 161/581] Add Prettier config for JS/TS/HTML formatting This helps ensure a consistent code style and helps editors like Zed that do LSP format-on-save by default. --- .prettierrc | 7 +++++++ Makefile | 3 +++ 2 files changed, 10 insertions(+) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..afa02a3af3 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "useTabs": true, + "tabWidth": 4, + "semi": true, + "singleQuote": true, + "printWidth": 150, +} diff --git a/Makefile b/Makefile index 2e6a838bfd..f7bf95f97b 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,9 @@ dev: $(DEMO) format: clang-format -i $(LIBRARY_SOURCES) $(DEMO_SOURCES) $(GLTFPACK_SOURCES) +formatjs: + prettier -w js/*.js gltf/*.js demo/*.html js/*.ts + js: js/meshopt_decoder.js js/meshopt_decoder.module.js js/meshopt_encoder.js js/meshopt_encoder.module.js js/meshopt_simplifier.js js/meshopt_simplifier.module.js symbols: $(BUILD)/amalgamated.so From 3dea31b5c248594a62f49a3e41fc88d7ceae2de3 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 22 Jul 2024 10:40:31 -0700 Subject: [PATCH 162/581] js: Reformat all sources with Prettier --- demo/demo.html | 105 +++++++------- demo/index.html | 57 ++++---- demo/simplify.html | 139 ++++++++++-------- gltf/cli.js | 3 +- gltf/library.js | 80 +++++------ js/benchmark.js | 55 ++++---- js/index.js | 2 +- js/meshopt_decoder.js | 105 +++++++------- js/meshopt_decoder.module.js | 92 ++++++------ js/meshopt_decoder.test.js | 227 +++++++++++------------------- js/meshopt_decoder_reference.js | 193 ++++++++++++------------- js/meshopt_encoder.js | 68 ++++----- js/meshopt_encoder.module.d.ts | 8 +- js/meshopt_encoder.module.js | 55 ++++---- js/meshopt_encoder.test.js | 142 +++++-------------- js/meshopt_simplifier.js | 179 ++++++++++++++++++----- js/meshopt_simplifier.module.d.ts | 33 ++++- js/meshopt_simplifier.module.js | 166 ++++++++++++++++++---- js/meshopt_simplifier.test.js | 153 ++++++-------------- 19 files changed, 970 insertions(+), 892 deletions(-) diff --git a/demo/demo.html b/demo/demo.html index 3b32876a1a..7c871e74b9 100644 --- a/demo/demo.html +++ b/demo/demo.html @@ -1,66 +1,67 @@ - + - - + + - meshoptimizer - demo + meshoptimizer - demo - - + + - - - - - - + // Resize + window.addEventListener('resize', function () { + engine.resize(); + }); + + diff --git a/demo/index.html b/demo/index.html index c0aaf6c5ce..d177bb2906 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,9 +1,9 @@ - + meshoptimizer - demo - - + + @@ -37,7 +43,7 @@ diff --git a/demo/simplify.html b/demo/simplify.html index d4b9534470..5987d1febe 100644 --- a/demo/simplify.html +++ b/demo/simplify.html @@ -1,9 +1,9 @@ - + meshoptimizer - demo - - + + @@ -37,7 +43,7 @@