From c00ff8895642bdfa29c6352bf109998eeeaae95e Mon Sep 17 00:00:00 2001 From: michalharakal Date: Sun, 18 Oct 2026 22:21:09 +0200 Subject: [PATCH 1/2] feat(wasm): BF16/FP16 provider kernels, common KernelStrictness, matrix rows, sidecar features, aligned wasm-bench scenarios - WasmKernelProvider binds the existing skainet_bf16_matmul / skainet_fp16_matmul sidecar exports (resident contiguous weight, staged strided window). - WasmSimd.features() and a one-line install banner mirroring the JVM factory. - KernelStrictness moves to commonMain with a programmatic overrideEnabled switch; JVM/Android keep the system property. KernelDispatch and DefaultCpuOps.matmul fail fast in strict mode before their reference fallbacks. - Kernel support matrix: Float16 row, BF16/FP16 on wasm-simd128, Q6_K on native-ffm, new "Resident serving" table; drift gate covers Panama and FFM tiers when available. - wasm-bench runs the engine-* scenarios of jvm-cpu-publish on every tier; the ternary gemv is skipped where no ternary kernel is registered. - Docs: eager-execution wasm column and FP16 row, corrected gaps; dtype-model strict-mode section; CHANGELOG. --- CHANGELOG.md | 8 + .../main/kotlin/GenerateKernelMatrixTask.kt | 32 +++- .../main/kotlin/models/KernelSupportModels.kt | 1 + .../ROOT/pages/contributing/dtype-model.adoc | 11 +- .../pages/explanation/eager-execution.adoc | 44 +++-- .../reference/kernel-support-matrix.adoc | 27 ++- .../kotlin/sk/ainet/bench/wasm/Main.kt | 7 +- .../kotlin/sk/ainet/bench/wasm/Scenarios.kt | 163 ++++++++++++++++++ .../api/kernel/KernelStrictness.android.kt | 4 + .../backend/api/kernel/KernelDispatch.kt | 7 + .../backend/api/kernel/KernelStrictness.kt | 32 ++-- .../api/kernel/KernelStrictness.other.kt | 3 + .../api/kernel/KernelStrictness.jvm.kt | 4 + .../api/kernel/KernelStrictness.other.kt | 3 + .../api/kernel/KernelStrictness.other.kt | 3 + .../api/kernel/KernelStrictness.other.kt | 3 + .../sk/ainet/exec/tensor/ops/DefaultCpuOps.kt | 10 +- .../exec/kernel/KernelSupportMatrixTest.kt | 47 ++++- .../sk/ainet/exec/wasm/WasmKernelProvider.kt | 63 +++++++ .../kotlin/sk/ainet/exec/wasm/WasmKernels.kt | 54 ++++++ .../kotlin/sk/ainet/exec/wasm/WasmSimd.kt | 5 + .../sk/ainet/exec/wasm/WasmSimdParityTest.kt | 67 +++++++ 22 files changed, 552 insertions(+), 46 deletions(-) create mode 100644 skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Scenarios.kt create mode 100644 skainet-backends/skainet-backend-api/src/androidMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.android.kt rename skainet-backends/skainet-backend-api/src/{jvmMain => commonMain}/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.kt (61%) create mode 100644 skainet-backends/skainet-backend-api/src/jsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt create mode 100644 skainet-backends/skainet-backend-api/src/jvmMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.jvm.kt create mode 100644 skainet-backends/skainet-backend-api/src/nativeMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt create mode 100644 skainet-backends/skainet-backend-api/src/wasmJsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt create mode 100644 skainet-backends/skainet-backend-api/src/wasmWasiMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index adc562c5e..63e4a7eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## [Unreleased] +### Added + +- **BF16 and FP16 matmul on the wasm tier**: `WasmKernelProvider` now binds the sidecar's `skainet_bf16_matmul` / `skainet_fp16_matmul` exports (`WasmBf16MatmulKernel`, `WasmFp16MatmulKernel`), so 16-bit dense weights no longer fall to the scalar kernels in a browser; a contiguous weight stays resident in the sidecar after its first call. +- **`WasmSimd.features()` / `WasmKernels.features()`**: mode, SIMD128, threads, cross-origin isolation, logical cores and resident weight bytes — the wasm counterpart of the JVM provider banner. `WasmSimd.install()` prints one `[SKaiNET] Using SIMD128 sidecar kernels (…)` line like the JVM factory does. +- **`KernelStrictness` is common code** (was JVM-only): `KernelStrictness.overrideEnabled` is the programmatic switch on every target; the JVM and Android still read `-Dskainet.strict.kernels`. `KernelDispatch` fails fast before the decoding reference fallback and `DefaultCpuOps.matmul` before the generic per-element loop, so strict mode means the same thing on every tier. +- **Kernel support matrix**: a `Float16` row, BF16/FP16 in the wasm column, Q6_K corrected to `native-ffm` on the JVM (the provider has had the kernel; the declared tier had not), and a third table, *Resident serving*, naming the sidecar-resident weights that stand in for mapped serving on JS/WASM. `KernelSupportMatrixTest` now gates the declared Panama and FFM tiers against what the providers expose. +- **`wasm-bench` runs the `engine-*` scenarios** of the JVM publish harness (`engine-fp32-gemm`, `engine-kernel-matmul`, `engine-bf16-matmul`, `engine-q8-matmul`, `engine-q4-gemm`, `engine-ternary-f32-gemv`, `engine-elementwise-add`, `engine-reductions-sum/mean`) with identical shapes and metrics on every tier it measures, so the JVM and wasm numbers sit in one table. + ## [0.61.0] - 2026-10-16 Headline: **the browser lane (SKEEP-007): packed SIMD128 kernels, quantize-at-load, and no more diff --git a/build-logic/convention/src/main/kotlin/GenerateKernelMatrixTask.kt b/build-logic/convention/src/main/kotlin/GenerateKernelMatrixTask.kt index bb422504f..6964d6e02 100644 --- a/build-logic/convention/src/main/kotlin/GenerateKernelMatrixTask.kt +++ b/build-logic/convention/src/main/kotlin/GenerateKernelMatrixTask.kt @@ -49,8 +49,10 @@ abstract class GenerateKernelMatrixTask : DefaultTask() { appendLine( "Each cell is the best (highest-priority) provider that serves " + "`${module.inputDtype} × format` `${module.op}` on that platform: " + - "*native-ffm* (100) → *panama-vector* (50) → *scalar* (0). An empty cell " + - "(`—`) means no provider carries a kernel there (the format is dequant-to-FP32 only).", + "*native-ffm* / *native-jni* / *native-cinterop* (100) → *panama-vector* / " + + "*wasm-simd128* (50) → *scalar* (0). An empty cell " + + "(`—`) means no provider carries a kernel there (the format is dequant-to-FP32 only). " + + "The JS/WASM column assumes `WasmSimd.install()` has run; without the sidecar it is the scalar floor.", ) appendLine("") if (module.formats.isEmpty() || module.platforms.isEmpty()) { @@ -100,6 +102,32 @@ abstract class GenerateKernelMatrixTask : DefaultTask() { appendLine("|===") appendLine("") } + if (module.resident.isNotEmpty()) { + appendLine("== Resident serving (sidecar memory)") + appendLine("") + appendLine( + "The browser has no files to map, so the wasm tier keeps weights *resident* in the " + + "SIMD128 sidecar's linear memory instead: each weight is uploaded once on its first " + + "matmul and every later call reads it in place (`WasmKernels.weightHandle`). This is " + + "the JS/WASM counterpart of mapped serving above — no per-call copy of the weight, " + + "no prepack — bounded by the wasm32 4 GB linear memory rather than the page cache. " + + "The other platforms serve from the heap, off-heap or the mapping and have no cell here.", + ) + appendLine("") + appendLine("[cols=\"$colSpec\", options=\"header\"]") + appendLine("|===") + append("| Weight format ") + module.platforms.forEach { append("| $it ") } + appendLine("") + appendLine("") + module.resident.forEach { fmt -> + append("| `${fmt.name}` ") + module.platforms.forEach { p -> append("| ${fmt.byPlatform[p] ?: "—"} ") } + appendLine("") + } + appendLine("|===") + appendLine("") + } appendLine( "See also the eager backends & kernels mindmap " + "(xref:explanation/eager-execution.adoc[]) for the narrative overview and gaps.", diff --git a/build-logic/convention/src/main/kotlin/models/KernelSupportModels.kt b/build-logic/convention/src/main/kotlin/models/KernelSupportModels.kt index 1084af35e..90da53887 100644 --- a/build-logic/convention/src/main/kotlin/models/KernelSupportModels.kt +++ b/build-logic/convention/src/main/kotlin/models/KernelSupportModels.kt @@ -22,6 +22,7 @@ data class KernelSupportModule( * prepack. Absent/empty in pre-#1189 JSON, so old files stay decodable. */ val mapped: List = emptyList(), + val resident: List = emptyList(), ) @Serializable diff --git a/docs/modules/ROOT/pages/contributing/dtype-model.adoc b/docs/modules/ROOT/pages/contributing/dtype-model.adoc index 43e57e521..8d3e4d13f 100644 --- a/docs/modules/ROOT/pages/contributing/dtype-model.adoc +++ b/docs/modules/ROOT/pages/contributing/dtype-model.adoc @@ -105,11 +105,18 @@ affordance today (W4, shipped): java -Dskainet.strict.kernels=true … ---- +[source,kotlin] +---- +KernelStrictness.overrideEnabled = true // every target; the only switch on JS, Wasm and Kotlin/Native +---- + When set, `DefaultCpuOpsJvm.matmul` raises `NoSuchKernelException` (with the failing dtype pair and the list of currently-registered providers) just before its silent scalar -fallback would have run. Default off — adaptive behaviour is -preserved. +fallback would have run; on every tier `KernelDispatch` raises it +before the decoding reference kernel and `DefaultCpuOps.matmul` +before the generic per-element loop. Default off — adaptive +behaviour is preserved. The constraint-resolution pass (W7) raises the same exception shape at *graph-prep* time, before forward execution can even diff --git a/docs/modules/ROOT/pages/explanation/eager-execution.adoc b/docs/modules/ROOT/pages/explanation/eager-execution.adoc index c2aa8d98f..ff94753b2 100644 --- a/docs/modules/ROOT/pages/explanation/eager-execution.adoc +++ b/docs/modules/ROOT/pages/explanation/eager-execution.adoc @@ -52,28 +52,32 @@ mindmap == Kernel × provider (matmul, FP32 activations) -[cols="2,1,1,1,1,1",options="header"] +[cols="2,1,1,1,1,1,1",options="header"] |=== -| Weight format | Scalar (all targets) | Panama (JVM) | Native FFM (JVM) | Native JNI (Android) | Native cinterop (K/N) -| FP32 | ✅ | ✅ | ✅ | ❌ | ❌ -| BF16 | ✅ | ✅ | ✅ | ❌ | ❌ -| Q8_0 | ✅ | ✅ | ✅ | ✅ | ✅ -| Q4_0 | ✅ | ✅ | ✅ | ✅ | ✅ -| Q4_K | ✅ | ✅ | ✅ | ✅ | ✅ -| Q6_K | ✅ | ✅ | ❌ | ✅ | ✅ -| Q5_K | ✅ | ✅ | ✅ | ✅ | ✅ -| Q5_1 | ✅ | ✅ | ✅ | ✅ | ✅ -| Q5_0 | ✅ | ✅ | ✅ | ✅ | ✅ -| TQ2_0 / BitNet b1.58 (int8 activations) | ✅ | — | — | ✅ NEON | — -| BitNet b1.58 (exact FP32 activations, vendored NeoGPU kernel) | ✅ | ✅ FFM | — | ✅ JNI + fused lm_head | ✅ K/N cinterop -| BITNET_PLANES (multi-plane ternary packing) | ✅ | via kernel pack | — | via kernel pack | via kernel pack -| Q2_K / Q3_K / Q8_K / IQ4 | ❌ (dequant to FP32 only) | ❌ | ❌ | ❌ | ❌ +| Weight format | Scalar (all targets) | Panama (JVM) | Native FFM (JVM) | Native JNI (Android) | Native cinterop (K/N) | Wasm SIMD128 (wasmJs) +| FP32 | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ +| BF16 | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ +| FP16 | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ +| Q8_0 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ +| Q4_0 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ +| Q4_K | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ +| Q6_K | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ +| Q5_K | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ +| Q5_1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ +| Q5_0 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ +| TQ2_0 / BitNet b1.58 (int8 activations) | ✅ | — | — | ✅ NEON | — | — +| BitNet b1.58 (exact FP32 activations, vendored NeoGPU kernel) | ✅ | ✅ FFM | — | ✅ JNI + fused lm_head | ✅ K/N cinterop | ❌ (reference) +| BITNET_PLANES (multi-plane ternary packing) | ✅ | via kernel pack | — | via kernel pack | via kernel pack | ❌ (reference) +| Q2_K / Q3_K / Q8_K / IQ4 | ❌ (dequant to FP32 only) | ❌ | ❌ | ❌ | ❌ | ❌ |=== Resolution is by priority: *Native (100 — whichever of FFM/JNI/cinterop applies to the target) → -Panama (50, JVM only) → Scalar (0)*. The best *available* provider that carries the kernel wins; +Panama / Wasm SIMD128 (50) → Scalar (0)*. The best *available* provider that carries the kernel wins; otherwise it cascades down. At most one native tier is compiled into a given target, so the native -columns are mutually exclusive per platform rather than stacked. +columns are mutually exclusive per platform rather than stacked. The Wasm SIMD128 column is the +sidecar pack (`skainet-backend-wasm-simd`), present only after `WasmSimd.install()`; the explicit +SIMD128 bodies are Q8_0, Q4_0 and dense `x · Wᵀ`, the other formats run the portable C body +auto-vectorised by Emscripten. Packed weights reach a kernel through the registry by declaring their xref:explanation/packed-weight-layout.adoc[block order]; a canonical weight is relayouted once, @@ -96,7 +100,11 @@ Packed-quant matmul works on every target: those formats have a `commonMain` sca == Gaps -* *Native FFM Q6_K* — the only packed format the FFM C kernel set does not cover. +* *Wasm ternary / BitNet* — the ternary gemv and planes lm-head kernels are not in the sidecar +build yet, so BitNet models in a browser run the decoding reference kernel. +* *Wasm beyond matmul* — elementwise, activations, reductions, normalisation and attention are the +common scalar Kotlin paths on wasmJs; Kotlin/Wasm has no SIMD types and no shared-memory threads, so +these follow the matmuls into the sidecar (SKEEP-007 rollout step 3). * *Native JNI dense FP32/BF16* — the Android JNI provider has no GEMM shim, so dense ops fall through to scalar there whichever `.so` tier loaded (SKaiNET#920). * *Dense FP32/BF16 SIMD on Kotlin/Native linux* — still the scalar floor; Apple has Accelerate diff --git a/docs/modules/ROOT/pages/reference/kernel-support-matrix.adoc b/docs/modules/ROOT/pages/reference/kernel-support-matrix.adoc index f655ab587..a3317ed37 100644 --- a/docs/modules/ROOT/pages/reference/kernel-support-matrix.adoc +++ b/docs/modules/ROOT/pages/reference/kernel-support-matrix.adoc @@ -3,18 +3,19 @@ Generated from `kernel-support.json` (version `0.61.0`) by `KernelSupportMatrixTest` — registry introspection of the registered `KernelProvider` implementations. Do not edit by hand; run `./gradlew generateKernelMatrix` to refresh. -Each cell is the best (highest-priority) provider that serves `Float32 × format` `matmul` on that platform: *native-ffm* (100) → *panama-vector* (50) → *scalar* (0). An empty cell (`—`) means no provider carries a kernel there (the format is dequant-to-FP32 only). +Each cell is the best (highest-priority) provider that serves `Float32 × format` `matmul` on that platform: *native-ffm* / *native-jni* / *native-cinterop* (100) → *panama-vector* / *wasm-simd128* (50) → *scalar* (0). An empty cell (`—`) means no provider carries a kernel there (the format is dequant-to-FP32 only). The JS/WASM column assumes `WasmSimd.install()` has run; without the sidecar it is the scalar floor. [cols="1,1,1,1,1,1", options="header"] |=== | Weight format | JVM | Android | Native·linux | Native·apple | JS/WASM | `Float32` | native-ffm | scalar | scalar | scalar | wasm-simd128 -| `BFloat16` | native-ffm | scalar | scalar | scalar | scalar +| `BFloat16` | native-ffm | scalar | scalar | scalar | wasm-simd128 +| `Float16` | native-ffm | scalar | scalar | scalar | wasm-simd128 | `Q8_0` | native-ffm | native-jni | native-cinterop | native-cinterop | wasm-simd128 | `Q4_0` | native-ffm | native-jni | native-cinterop | native-cinterop | wasm-simd128 | `Q4_K` | native-ffm | native-jni | native-cinterop | native-cinterop | wasm-simd128 -| `Q6_K` | panama-vector | native-jni | native-cinterop | native-cinterop | wasm-simd128 +| `Q6_K` | native-ffm | native-jni | native-cinterop | native-cinterop | wasm-simd128 | `Q5_K` | native-ffm | native-jni | native-cinterop | native-cinterop | wasm-simd128 | `Q5_1` | native-ffm | native-jni | native-cinterop | native-cinterop | wasm-simd128 | `Q5_0` | native-ffm | native-jni | native-cinterop | native-cinterop | wasm-simd128 @@ -37,4 +38,24 @@ Kernels that read the weight in canonical row-major GGUF file order straight fro | `Q5_0` | ffm-rowmajor | native-jni-direct | — | — | — |=== +== Resident serving (sidecar memory) + +The browser has no files to map, so the wasm tier keeps weights *resident* in the SIMD128 sidecar's linear memory instead: each weight is uploaded once on its first matmul and every later call reads it in place (`WasmKernels.weightHandle`). This is the JS/WASM counterpart of mapped serving above — no per-call copy of the weight, no prepack — bounded by the wasm32 4 GB linear memory rather than the page cache. The other platforms serve from the heap, off-heap or the mapping and have no cell here. + +[cols="1,1,1,1,1,1", options="header"] +|=== +| Weight format | JVM | Android | Native·linux | Native·apple | JS/WASM + +| `Float32` | — | — | — | — | wasm-resident +| `BFloat16` | — | — | — | — | wasm-resident +| `Float16` | — | — | — | — | wasm-resident +| `Q8_0` | — | — | — | — | wasm-resident +| `Q4_0` | — | — | — | — | wasm-resident +| `Q4_K` | — | — | — | — | wasm-resident +| `Q6_K` | — | — | — | — | wasm-resident +| `Q5_K` | — | — | — | — | wasm-resident +| `Q5_1` | — | — | — | — | wasm-resident +| `Q5_0` | — | — | — | — | wasm-resident +|=== + See also the eager backends & kernels mindmap (xref:explanation/eager-execution.adoc[]) for the narrative overview and gaps. diff --git a/skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Main.kt b/skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Main.kt index 5a61c3071..72c130075 100644 --- a/skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Main.kt +++ b/skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Main.kt @@ -21,7 +21,9 @@ import kotlin.time.TimeSource * * `[SKAINET_PERF_WASM] m= n= k= form= ms= gflops=` * - * Every later tier (SIMD128 sidecar, quantize-at-load) is measured against these lines. + * Every later tier (SIMD128 sidecar, quantize-at-load) is measured against these lines. Each pass + * also runs the `engine-*` scenarios of the JVM publish harness ([runEngineScenarios]) so the two + * tiers are compared on identical shapes. */ private data class Case(val name: String, val m: Int, val n: Int, val k: Int) @@ -107,7 +109,8 @@ suspend fun main() { private fun runPass(tier: String) { val ctx = DirectCpuExecutionContext() - println("[SKAINET_PERF_WASM] tier=$tier backend=${ctx.ops::class.simpleName} cases=${cases.size}") + println("[SKAINET_PERF_WASM] tier=$tier backend=${ctx.ops::class.simpleName} cases=${cases.size} features=${WasmKernels.features()}") + runEngineScenarios(tier) for (case in cases) { val x = ctx.fromFloatArray(Shape(case.m, case.k), FP32::class, pseudo(case.m * case.k, 3)) val dense = ctx.fromFloatArray(Shape(case.n, case.k), FP32::class, pseudo(case.n * case.k, 7)) diff --git a/skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Scenarios.kt b/skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Scenarios.kt new file mode 100644 index 000000000..271fc27be --- /dev/null +++ b/skainet-backends/benchmarks/wasm-bench/src/wasmJsMain/kotlin/sk/ainet/bench/wasm/Scenarios.kt @@ -0,0 +1,163 @@ +package sk.ainet.bench.wasm + +import sk.ainet.backend.api.kernel.KernelDispatch +import sk.ainet.backend.api.kernel.KernelKey +import sk.ainet.backend.api.kernel.KernelRegistry +import sk.ainet.context.DirectCpuExecutionContext +import sk.ainet.lang.memory.Scope +import sk.ainet.lang.memory.Storage +import sk.ainet.lang.memory.TensorView +import sk.ainet.lang.tensor.Shape +import sk.ainet.lang.tensor.data.BitNetB158TensorData +import sk.ainet.lang.types.FP32 +import kotlin.math.roundToInt +import kotlin.time.TimeSource + +/** + * The `engine-*` scenarios of `skainet-backends/benchmarks/jvm-cpu-publish`, run on the wasm tier + * with the same shapes, data generators and metrics, so one table compares the two tiers: + * + * `[SKAINET_PERF_WASM] tier= scenario= metric= value= ` + * + * Kernel scenarios take the best registered provider (`scalar` before `WasmSimd.install()`, + * `wasm-simd128` after); ops scenarios go through a fresh `DirectCpuExecutionContext`, exactly as + * the JVM harness does. A scenario the tier cannot serve yet prints `value=skipped reason=…`. + */ +internal class WasmScenario( + val id: String, + val metric: String, + val params: Map, + val reps: Int, + val setup: () -> (() -> Double), +) + +private fun lcg(seed: Int): () -> Float { + var s = seed + return { + s = s * 1103515245 + 12345 + ((s ushr 16) and 0x7FFF) / 32768f + } +} + +internal fun engineScenarios(): List = listOf( + WasmScenario("engine-fp32-gemm", "gflops", mapOf("size" to "1024"), reps = 3) { + val n = 1024 + val ctx = DirectCpuExecutionContext() + val a = ctx.fromFloatArray(Shape(n, n), FP32::class, FloatArray(n * n) { ((it % 251) - 125).toFloat() / 127f }) + val b = ctx.fromFloatArray(Shape(n, n), FP32::class, FloatArray(n * n) { ((it * 13 % 257) - 128).toFloat() / 127f }) + val flops = 2.0 * n * n * n; + { flops / seconds { ctx.ops.matmul(a, b) } / 1e9 } + }, + WasmScenario("engine-kernel-matmul", "gflops", mapOf("size" to "1024"), reps = 3) { + val n = 1024 + DirectCpuExecutionContext() + val kernel = checkNotNull(KernelRegistry.bestAvailable()?.matmulFp32()) { "no FP32 kernel" } + val a = FloatArray(n * n) { ((it % 251) - 125).toFloat() / 127f } + val b = FloatArray(n * n) { ((it * 13 % 257) - 128).toFloat() / 127f } + val out = FloatArray(n * n) + val flops = 2.0 * n * n * n; + { flops / seconds { kernel.matmul(a, 0, n, b, 0, n, out, 0, n, n, n, n) } / 1e9 } + }, + WasmScenario("engine-bf16-matmul", "gflops", mapOf("m" to "1024", "n" to "1024", "k" to "1024"), reps = 3) { + val n = 1024 + DirectCpuExecutionContext() + val kernel = checkNotNull(KernelRegistry.bestAvailable()?.matmulBf16()) { "no BF16 kernel" } + val rnd = lcg(n) + val a = FloatArray(n * n) { rnd() - 0.5f } + val b = ByteArray(n * n * 2) + for (i in 0 until n * n) { + val bits = (rnd() - 0.5f).toRawBits() ushr 16 + b[i * 2] = (bits and 0xFF).toByte() + b[i * 2 + 1] = ((bits ushr 8) and 0xFF).toByte() + } + val out = FloatArray(n * n) + val flops = 2.0 * n * n * n; + { flops / seconds { kernel.matmul(a, 0, n, b, 0, n * 2, out, 0, n, n, n, n) } / 1e9 } + }, + WasmScenario("engine-q8-matmul", "gops", mapOf("input_dim" to "4096", "output_dim" to "4096"), reps = 10) { + val inputDim = 4096; val outputDim = 4096 + DirectCpuExecutionContext() + val kernel = checkNotNull(KernelRegistry.bestAvailable()?.matmulQ8_0()) { "no Q8_0 kernel" } + val numBlocks = inputDim / 32 * outputDim + val rnd = lcg(inputDim + outputDim) + val weight = ByteArray(numBlocks * 34) { (rnd() * 255f).toInt().toByte() } + for (block in 0 until numBlocks) { weight[block * 34] = 0x00; weight[block * 34 + 1] = 0x22 } + val input = FloatArray(inputDim) { rnd() - 0.5f } + val output = FloatArray(outputDim) + val ops = 2.0 * inputDim * outputDim; + { ops / seconds { kernel.matmul(input, 0, weight, 0, inputDim, outputDim, output, 0) } / 1e9 } + }, + WasmScenario("engine-q4-gemm", "gops", mapOf("input_dim" to "4096", "output_dim" to "4096"), reps = 10) { + val inputDim = 4096; val outputDim = 4096 + DirectCpuExecutionContext() + val kernel = checkNotNull(KernelRegistry.bestAvailable()?.matmulQ4K()) { "no Q4_K kernel" } + val numBlocks = inputDim / 256 * outputDim + val rnd = lcg(42) + val weight = ByteArray(numBlocks * 144) { (rnd() * 255f).toInt().toByte() } + for (block in 0 until numBlocks) { + val base = block * 144 + weight[base] = 0x00; weight[base + 1] = 0x3C; weight[base + 2] = 0x00; weight[base + 3] = 0x3C + } + val input = FloatArray(inputDim) { ((it % 251) - 125).toFloat() / 127f } + val output = FloatArray(outputDim) + val ops = 2.0 * inputDim * outputDim; + { ops / seconds { kernel.matmul(input, 0, weight, 0, inputDim, outputDim, output, 0) } / 1e9 } + }, + WasmScenario("engine-ternary-f32-gemv", "gops", mapOf("input_dim" to "2560", "output_dim" to "6912"), reps = 5) { + val inputDim = 2560; val outputDim = 6912 + val rnd = lcg(inputDim + outputDim) + val values = FloatArray(outputDim * inputDim) { ((rnd() * 3f).toInt() - 1) * 0.5f } + val weight = BitNetB158TensorData.fromFloats(Shape(outputDim, inputDim), values).packedView + val activation = TensorView.dense(Storage.Heap.wrap(FloatArray(inputDim) { rnd() - 0.5f }), Shape(1, inputDim), FP32) + // The decoding reference kernel is orders of magnitude slower than a real kernel and + // takes hours at this shape on wasm; measure only when a ternary kernel is registered. + checkNotNull(KernelDispatch.find(KernelKey.matmul(activation, weight))) { "no ternary kernel registered on this tier" } + val out = TensorView.dense(Storage.Heap.floats(outputDim), Shape(1, outputDim), FP32) + val ops = 2.0 * inputDim * outputDim; + { ops / seconds { KernelDispatch.matmul(activation, weight, out, Scope.Ambient) } / 1e9 } + }, + WasmScenario("engine-elementwise-add", "melems_per_sec", mapOf("elements" to "1000000"), reps = 10) { + val n = 1_000_000 + val ctx = DirectCpuExecutionContext() + val a = ctx.fromFloatArray(Shape(n), FP32::class, FloatArray(n) { it.toFloat() * 0.5f }) + val b = ctx.fromFloatArray(Shape(n), FP32::class, FloatArray(n) { 1f }); + { n / seconds { ctx.ops.add(a, b) } / 1e6 } + }, + WasmScenario("engine-reductions-sum", "melems_per_sec", mapOf("elements" to "1000000", "op" to "sum"), reps = 10) { + val n = 1_000_000 + val ctx = DirectCpuExecutionContext() + val a = ctx.fromFloatArray(Shape(n), FP32::class, FloatArray(n) { (it % 1024).toFloat() * 0.25f }); + { n / seconds { ctx.ops.sum(a) } / 1e6 } + }, + WasmScenario("engine-reductions-mean", "melems_per_sec", mapOf("elements" to "1000000", "op" to "mean"), reps = 10) { + val n = 1_000_000 + val ctx = DirectCpuExecutionContext() + val a = ctx.fromFloatArray(Shape(n), FP32::class, FloatArray(n) { (it % 1024).toFloat() * 0.25f }); + { n / seconds { ctx.ops.mean(a) } / 1e6 } + }, +) + +private inline fun seconds(block: () -> Unit): Double { + val t0 = TimeSource.Monotonic.markNow() + block() + return t0.elapsedNow().inWholeNanoseconds / 1e9 +} + +/** Run every scenario once for warm-up, then report the median of [WasmScenario.reps] runs. */ +internal fun runEngineScenarios(tier: String) { + for (s in engineScenarios()) { + val params = s.params.entries.joinToString(" ") { "${it.key}=${it.value}" } + val run = try { + s.setup() + } catch (e: Throwable) { + println("[SKAINET_PERF_WASM] tier=$tier scenario=${s.id} metric=${s.metric} value=skipped reason=${e.message} $params") + continue + } + run() + val samples = DoubleArray(s.reps) { run() } + samples.sort() + val median = samples[s.reps / 2] + val text = ((median * 100).roundToInt() / 100.0).toString() + println("[SKAINET_PERF_WASM] tier=$tier scenario=${s.id} metric=${s.metric} value=$text kernel=${KernelRegistry.bestAvailable()?.name} $params") + } +} diff --git a/skainet-backends/skainet-backend-api/src/androidMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.android.kt b/skainet-backends/skainet-backend-api/src/androidMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.android.kt new file mode 100644 index 000000000..ebc6c83e5 --- /dev/null +++ b/skainet-backends/skainet-backend-api/src/androidMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.android.kt @@ -0,0 +1,4 @@ +package sk.ainet.backend.api.kernel + +internal actual fun platformStrictKernels(): Boolean = + System.getProperty(KernelStrictness.SYSTEM_PROPERTY) == "true" diff --git a/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/kernel/KernelDispatch.kt b/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/kernel/KernelDispatch.kt index dfbbb7944..468dce0ff 100644 --- a/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/kernel/KernelDispatch.kt +++ b/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/kernel/KernelDispatch.kt @@ -202,6 +202,13 @@ public object KernelDispatch { // blocked weight (per-element block decode) — a process that lands here on a quantized // weight almost certainly forgot to install a kernel pack. Say so once, loudly, even with // no sink attached: silent fallback is how a 25 s/token regression ships unnoticed. + if (b.layout.blocked) { + KernelStrictness.failIfStrict { + "matmul (activation=${a.format.encoding}, weight=${b.format.encoding}, " + + "order=${b.layout.blockOrder}) has no registered kernel; would fall back to the " + + "decoding reference kernel. Registered: ${kernels().joinToString { it.name }.ifEmpty { "" }}" + } + } if (!warnedReferenceFallback && b.layout.blocked) { warnedReferenceFallback = true println( diff --git a/skainet-backends/skainet-backend-api/src/jvmMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.kt b/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.kt similarity index 61% rename from skainet-backends/skainet-backend-api/src/jvmMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.kt rename to skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.kt index ad4720485..ac3c4b3b7 100644 --- a/skainet-backends/skainet-backend-api/src/jvmMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.kt +++ b/skainet-backends/skainet-backend-api/src/commonMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.kt @@ -9,31 +9,36 @@ package sk.ainet.backend.api.kernel * rather than as a silent perf regression at forward time (e.g. a * Q4_K matmul that falls back to a scalar dequant + FP32 matmul). * - * This object provides the smallest possible affordance: a system - * property (`-Dskainet.strict.kernels=true`) flips the runtime into - * fail-fast mode. Dispatch sites call [failIfStrict] right before - * they would otherwise silently fall back; the call is a no-op when - * strict mode is off, preserving the existing adaptive behaviour. + * The switch is common code so every tier honours it the same way: + * [overrideEnabled] is the programmatic setting (the only one on JS, Wasm and + * Kotlin/Native, which have no property store); when it is `null` the platform + * setting is read — `-Dskainet.strict.kernels=true` on the JVM and Android. + * Dispatch sites call [failIfStrict] right before they would otherwise silently + * fall back; the call is a no-op when strict mode is off, preserving the + * existing adaptive behaviour. * * Per-context strict mode (e.g. `DirectCpuExecutionContext.create(strict = true)`) * is a follow-up that requires plumbing the flag through every - * platform's `platformDefaultCpuOpsFactory`. The system-property - * affordance is sufficient for tests, CI, and debugging — the - * primary use cases — and ships with zero cross-platform plumbing. + * platform's `platformDefaultCpuOpsFactory`. */ public object KernelStrictness { - /** System-property name that flips fail-fast mode on. */ + /** System-property name that flips fail-fast mode on (JVM and Android). */ public const val SYSTEM_PROPERTY: String = "skainet.strict.kernels" + /** + * Programmatic switch; `null` means "read the platform setting". This is the + * only switch on targets without system properties. + */ + public var overrideEnabled: Boolean? = null + /** * Returns `true` when the runtime should fail fast instead of - * falling back. Reads the system property on every call so a + * falling back. Reads the platform setting on every call so a * test can toggle it via `System.setProperty(...)` between * cases without restarting the JVM. */ - public fun isEnabled(): Boolean = - System.getProperty(SYSTEM_PROPERTY) == "true" + public fun isEnabled(): Boolean = overrideEnabled ?: platformStrictKernels() /** * Throws [NoSuchKernelException] with the supplied message @@ -48,6 +53,9 @@ public object KernelStrictness { } } +/** Platform reading of [KernelStrictness.SYSTEM_PROPERTY]; `false` where there is no property store. */ +internal expect fun platformStrictKernels(): Boolean + /** * Raised by dispatch sites when [KernelStrictness] is enabled and * no registered kernel matches the requested op/dtype combination. diff --git a/skainet-backends/skainet-backend-api/src/jsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt b/skainet-backends/skainet-backend-api/src/jsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt new file mode 100644 index 000000000..956e7802f --- /dev/null +++ b/skainet-backends/skainet-backend-api/src/jsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt @@ -0,0 +1,3 @@ +package sk.ainet.backend.api.kernel + +internal actual fun platformStrictKernels(): Boolean = false diff --git a/skainet-backends/skainet-backend-api/src/jvmMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.jvm.kt b/skainet-backends/skainet-backend-api/src/jvmMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.jvm.kt new file mode 100644 index 000000000..ebc6c83e5 --- /dev/null +++ b/skainet-backends/skainet-backend-api/src/jvmMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.jvm.kt @@ -0,0 +1,4 @@ +package sk.ainet.backend.api.kernel + +internal actual fun platformStrictKernels(): Boolean = + System.getProperty(KernelStrictness.SYSTEM_PROPERTY) == "true" diff --git a/skainet-backends/skainet-backend-api/src/nativeMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt b/skainet-backends/skainet-backend-api/src/nativeMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt new file mode 100644 index 000000000..956e7802f --- /dev/null +++ b/skainet-backends/skainet-backend-api/src/nativeMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt @@ -0,0 +1,3 @@ +package sk.ainet.backend.api.kernel + +internal actual fun platformStrictKernels(): Boolean = false diff --git a/skainet-backends/skainet-backend-api/src/wasmJsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt b/skainet-backends/skainet-backend-api/src/wasmJsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt new file mode 100644 index 000000000..956e7802f --- /dev/null +++ b/skainet-backends/skainet-backend-api/src/wasmJsMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt @@ -0,0 +1,3 @@ +package sk.ainet.backend.api.kernel + +internal actual fun platformStrictKernels(): Boolean = false diff --git a/skainet-backends/skainet-backend-api/src/wasmWasiMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt b/skainet-backends/skainet-backend-api/src/wasmWasiMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt new file mode 100644 index 000000000..956e7802f --- /dev/null +++ b/skainet-backends/skainet-backend-api/src/wasmWasiMain/kotlin/sk/ainet/backend/api/kernel/KernelStrictness.other.kt @@ -0,0 +1,3 @@ +package sk.ainet.backend.api.kernel + +internal actual fun platformStrictKernels(): Boolean = false diff --git a/skainet-backends/skainet-backend-cpu/src/commonMain/kotlin/sk/ainet/exec/tensor/ops/DefaultCpuOps.kt b/skainet-backends/skainet-backend-cpu/src/commonMain/kotlin/sk/ainet/exec/tensor/ops/DefaultCpuOps.kt index db6da6530..f340df8e1 100644 --- a/skainet-backends/skainet-backend-cpu/src/commonMain/kotlin/sk/ainet/exec/tensor/ops/DefaultCpuOps.kt +++ b/skainet-backends/skainet-backend-cpu/src/commonMain/kotlin/sk/ainet/exec/tensor/ops/DefaultCpuOps.kt @@ -711,7 +711,15 @@ public open class DefaultCpuOpsBase( // legacy per-element fallback stays one flag away (skainet.dispatch.registry=false) until the // migration is complete. return KernelProfile.timeGeneric { - dispatchMatmulViaRegistry(a, b) ?: matmulGeneric(a, b) + dispatchMatmulViaRegistry(a, b) ?: run { + // Fail-fast point shared by every tier: the legacy per-element path is the silent + // fallback strict mode exists to catch (the JVM subclass checks its SPI paths first). + sk.ainet.backend.api.kernel.KernelStrictness.failIfStrict { + "matmul (${a.dtype.simpleName} ${a.shape} × ${b.dtype.simpleName} ${b.shape}) is not " + + "expressible for KernelDispatch; would fall back to the generic per-element loop" + } + matmulGeneric(a, b) + } } } diff --git a/skainet-backends/skainet-backend-native-cpu/src/jvmTest/kotlin/sk/ainet/exec/kernel/KernelSupportMatrixTest.kt b/skainet-backends/skainet-backend-native-cpu/src/jvmTest/kotlin/sk/ainet/exec/kernel/KernelSupportMatrixTest.kt index 798327990..84bf97d50 100644 --- a/skainet-backends/skainet-backend-native-cpu/src/jvmTest/kotlin/sk/ainet/exec/kernel/KernelSupportMatrixTest.kt +++ b/skainet-backends/skainet-backend-native-cpu/src/jvmTest/kotlin/sk/ainet/exec/kernel/KernelSupportMatrixTest.kt @@ -28,7 +28,7 @@ class KernelSupportMatrixTest { @AfterTest fun reset() = KernelDispatch.clearForTesting() - private val formats = listOf("Float32", "BFloat16", "Q8_0", "Q4_0", "Q4_K", "Q6_K", "Q5_K", "Q5_1", "Q5_0") + private val formats = listOf("Float32", "BFloat16", "Float16", "Q8_0", "Q4_0", "Q4_K", "Q6_K", "Q5_K", "Q5_1", "Q5_0") // platform key (display) -> the set of providers (by source-set) reaching it. private val platforms = listOf("JVM", "Android", "Native·linux", "Native·apple", "JS/WASM") @@ -48,9 +48,11 @@ class KernelSupportMatrixTest { private fun tiers(): List = listOf( Tier("scalar", 0, platforms.toSet(), scalarFormats()), Tier("panama-vector", 50, setOf("JVM"), - setOf("Float32", "BFloat16", "Q8_0", "Q4_0", "Q4_K", "Q6_K", "Q5_K", "Q5_1", "Q5_0")), + setOf("Float32", "BFloat16", "Float16", "Q8_0", "Q4_0", "Q4_K", "Q6_K", "Q5_K", "Q5_1", "Q5_0")), + // native-ffm: every accessor of NativeKernelProvider, Q6_K included (DefaultCpuOps resolves + // `matmulQ6K()` from the best available provider, so the FFM kernel wins over Panama). Tier("native-ffm", 100, setOf("JVM"), - setOf("Float32", "BFloat16", "Q8_0", "Q4_0", "Q4_K", "Q5_K", "Q5_1", "Q5_0")), + setOf("Float32", "BFloat16", "Float16", "Q8_0", "Q4_0", "Q4_K", "Q6_K", "Q5_K", "Q5_1", "Q5_0")), Tier("native-jni", 100, setOf("Android"), setOf("Q8_0", "Q4_0", "Q4_K", "Q5_K", "Q6_K", "Q5_1", "Q5_0")), // native-cinterop: NativeKnKernelProvider (nativeMain) — the same C @@ -65,9 +67,22 @@ class KernelSupportMatrixTest { // kernels compiled by Emscripten into a SIMD128 sidecar module (SKEEP-007 Tier 1), with // pthreads on cross-origin-isolated pages and under Node. Installed by WasmSimd.install(); // without it the JS/WASM column is the scalar floor. The row-major `_rm` kernels are also - // served (WasmSimdKernelPack), heap-resident in the sidecar rather than mapped. + // served (WasmSimdKernelPack), heap-resident in the sidecar rather than mapped. BF16 and FP16 + // bind the sidecar's `skainet_bf16_matmul` / `skainet_fp16_matmul` exports. Tier("wasm-simd128", 50, setOf("JS/WASM"), - setOf("Float32", "Q8_0", "Q4_0", "Q4_K", "Q5_K", "Q6_K", "Q5_1", "Q5_0")), + setOf("Float32", "BFloat16", "Float16", "Q8_0", "Q4_0", "Q4_K", "Q5_K", "Q6_K", "Q5_1", "Q5_0")), + ) + + /** + * Resident serving: the wasm tier's counterpart of mapped serving. A browser has no file to map, + * so `WasmKernels.weightHandle` / `denseWeightHandle` upload each weight into the sidecar's linear + * memory once and every later matmul reads it in place — the dense and narrow-float kernels and + * all seven packed `_rm` kernels. Hand-declared like the Android mapped row: nothing on a JVM + * test run can instantiate the sidecar. + */ + private fun residentTiers(): List = listOf( + Tier("wasm-resident", 50, setOf("JS/WASM"), + setOf("Float32", "BFloat16", "Float16", "Q8_0", "Q4_0", "Q4_K", "Q5_K", "Q6_K", "Q5_1", "Q5_0")), ) /** @@ -120,6 +135,16 @@ class KernelSupportMatrixTest { .append(cells.joinToString(", ")).append("}}") sb.append(if (i == mappedFormats.lastIndex) "\n" else ",\n") } + sb.append(" ],\n") + val resident = residentTiers() + val residentFormats = formats.filter { fmt -> resident.any { fmt in it.formats } } + sb.append(" \"resident\": [\n") + residentFormats.forEachIndexed { i, fmt -> + val cells = platforms.mapNotNull { p -> best(fmt, p, resident)?.let { "\"$p\": \"$it\"" } } + sb.append(" {\"name\": \"").append(fmt).append("\", \"byPlatform\": {") + .append(cells.joinToString(", ")).append("}}") + sb.append(if (i == residentFormats.lastIndex) "\n" else ",\n") + } sb.append(" ]\n}\n") return sb.toString() } @@ -131,7 +156,7 @@ class KernelSupportMatrixTest { // Drift gate on the scalar floor (the all-platform baseline): the documented set // below must equal what the scalar provider actually carries. Update both together. assertEquals( - setOf("Float32", "BFloat16", "Q8_0", "Q4_0", "Q4_K", "Q6_K", "Q5_K", "Q5_1", "Q5_0"), + setOf("Float32", "BFloat16", "Float16", "Q8_0", "Q4_0", "Q4_K", "Q6_K", "Q5_K", "Q5_1", "Q5_0"), scalarFormats(), "ScalarKernelProvider coverage changed — update the declared sets + run ./gradlew generateKernelMatrix", ) @@ -140,6 +165,16 @@ class KernelSupportMatrixTest { val providers: List = listOf(ScalarKernelProvider, PanamaVectorKernelProvider, NativeKernelProvider) assertEquals(3, providers.size) + // Drift gate on the declared JVM tiers, where the environment allows it: a provider whose + // accessors answer (`isAvailable()`) must expose exactly the hand-kept set, so a provider + // gaining or losing a kernel fails here. An unavailable provider (no Vector API module, no + // native library on this runner) is skipped — that is the env gate the KDoc describes. + fun exposed(p: KernelProvider) = formats.filter { p.supports("matmul", listOf("Float32", it)) }.toSet() + for (p in listOf(PanamaVectorKernelProvider, NativeKernelProvider)) { + if (!p.isAvailable()) continue + assertEquals(tiers.first { it.name == p.name }.formats, exposed(p), "${p.name} tier drifted from the provider") + } + // Drift gate on mapped serving (#1193): install the JVM-reachable mapped-capable // kernels and assert what they actually serve against StorageCapabilities' // hand-kept mirror — the two lists can't independently drift without failing this test. diff --git a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernelProvider.kt b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernelProvider.kt index 415103c29..77848742e 100644 --- a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernelProvider.kt +++ b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernelProvider.kt @@ -1,5 +1,7 @@ package sk.ainet.exec.wasm +import sk.ainet.backend.api.kernel.Bf16MatmulKernel +import sk.ainet.backend.api.kernel.Fp16MatmulKernel import sk.ainet.backend.api.kernel.Fp32MatmulKernel import sk.ainet.backend.api.kernel.KernelProvider import sk.ainet.backend.api.kernel.Q4KMatmulKernel @@ -21,6 +23,8 @@ public object WasmKernelProvider : KernelProvider { override fun isAvailable(): Boolean = WasmKernels.isReady override fun matmulFp32(): Fp32MatmulKernel = WasmFp32MatmulKernel + override fun matmulBf16(): Bf16MatmulKernel = WasmBf16MatmulKernel + override fun matmulFp16(): Fp16MatmulKernel = WasmFp16MatmulKernel override fun matmulQ8_0(): Q8_0MatmulKernel = object : Q8_0MatmulKernel { override fun matmul(input: FloatArray, inputOffset: Int, weight: ByteArray, weightByteOffset: Int, inputDim: Int, outputDim: Int, output: FloatArray, outputOffset: Int) = @@ -73,6 +77,65 @@ public object WasmKernelProvider : KernelProvider { } } +/** + * `C(m,n) = A(m,k) · B(k,n)` with `B` as 16-bit floats (`skainet_bf16_matmul` / `skainet_fp16_matmul`). + * A contiguous `B` (`bByteStride == 2 * n`, whole array) is a weight and stays resident after the + * first call; a strided or windowed `B` is staged per call, as the activation always is. + */ +internal class WasmNarrowFloatMatmulKernel(private val fn: String) { + fun matmul( + a: FloatArray, aOffset: Int, aStride: Int, + b: ByteArray, bByteOffset: Int, bByteStride: Int, + out: FloatArray, outOffset: Int, outStride: Int, + m: Int, n: Int, k: Int, + ) { + require(m >= 0 && n >= 0 && k >= 0) { "m, n, k must be non-negative; got m=$m n=$n k=$k" } + if (m == 0 || n == 0) return + val rowBytes = n * 2 + val resident = bByteStride == rowBytes && bByteOffset == 0 && b.size == k * rowBytes + val aPtr = WasmKernels.alloc(m * k * 4) + val bPtr = if (resident) WasmKernels.weightHandle(b, 0, b.size) else WasmKernels.alloc(k * rowBytes) + val cPtr = WasmKernels.alloc(m * n * 4) + try { + if (aStride == k) WasmKernels.writeFloats(aPtr, a, aOffset, m * k) + else for (i in 0 until m) WasmKernels.writeFloats(aPtr + i * k * 4, a, aOffset + i * aStride, k) + if (!resident) { + if (bByteStride == rowBytes) WasmKernels.writeBytes(bPtr, b, bByteOffset, k * rowBytes) + else for (p in 0 until k) WasmKernels.writeBytes(bPtr + p * rowBytes, b, bByteOffset + p * bByteStride, rowBytes) + } + WasmKernels.narrowFloatMatmul(fn, aPtr, k, bPtr, rowBytes, cPtr, n, m, n, k) + if (outStride == n) WasmKernels.readFloats(cPtr, out, outOffset, m * n) + else for (i in 0 until m) WasmKernels.readFloats(cPtr + i * n * 4, out, outOffset + i * outStride, n) + } finally { + WasmKernels.free(cPtr) + if (!resident) WasmKernels.free(bPtr) + WasmKernels.free(aPtr) + } + } +} + +/** BF16 weights in the sidecar (`skainet_bf16_matmul`). */ +public object WasmBf16MatmulKernel : Bf16MatmulKernel { + private val impl = WasmNarrowFloatMatmulKernel("_skainet_bf16_matmul") + override fun matmul( + a: FloatArray, aOffset: Int, aStride: Int, + b: ByteArray, bByteOffset: Int, bByteStride: Int, + out: FloatArray, outOffset: Int, outStride: Int, + m: Int, n: Int, k: Int, + ): Unit = impl.matmul(a, aOffset, aStride, b, bByteOffset, bByteStride, out, outOffset, outStride, m, n, k) +} + +/** FP16 weights in the sidecar (`skainet_fp16_matmul`). */ +public object WasmFp16MatmulKernel : Fp16MatmulKernel { + private val impl = WasmNarrowFloatMatmulKernel("_skainet_fp16_matmul") + override fun matmul( + a: FloatArray, aOffset: Int, aStride: Int, + b: ByteArray, bByteOffset: Int, bByteStride: Int, + out: FloatArray, outOffset: Int, outStride: Int, + m: Int, n: Int, k: Int, + ): Unit = impl.matmul(a, aOffset, aStride, b, bByteOffset, bByteStride, out, outOffset, outStride, m, n, k) +} + /** `C(m,n) = A(m,k) · B(k,n)` in the sidecar; both operands cross per call (dense weights are not cached). */ public object WasmFp32MatmulKernel : Fp32MatmulKernel { override fun matmul( diff --git a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernels.kt b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernels.kt index 5dcd0d2b5..19b00a64c 100644 --- a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernels.kt +++ b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmKernels.kt @@ -205,6 +205,43 @@ public object WasmKernels { /** `skainet_fp32_matmul_wt`: `out(m,n) = in(m,k) · w(n,k)ᵀ`. */ public fun fp32MatmulWt(inPtr: Int, wPtr: Int, outPtr: Int, m: Int, n: Int, k: Int): Unit = jsFp32MatmulWt(mod(), inPtr, wPtr, outPtr, m, n, k) + + /** + * `skainet_bf16_matmul` / `skainet_fp16_matmul`: `C(m,n) = A(m,k) · B(k,n)` with `B` stored as + * 16-bit floats, strides in floats for `A`/`C` and in bytes for `B`. + */ + public fun narrowFloatMatmul(fnName: String, aPtr: Int, aStride: Int, bPtr: Int, bByteStride: Int, cPtr: Int, cStride: Int, m: Int, n: Int, k: Int): Unit = + jsNarrowFloatMatmul(mod(), fnName, aPtr, aStride, bPtr, bByteStride, cPtr, cStride, m, n, k) + + // ── diagnostics ─────────────────────────────────────────────────────────────────────────────── + + /** + * What the sidecar runs on — the wasm counterpart of the JVM's provider banner and CPU-feature + * probes. [hardwareConcurrency] is the browser's (or Node's) logical core count, [threads] whether + * the pthreads build is loaded (it only is when [crossOriginIsolated] or under Node). + */ + public data class SidecarFeatures( + val mode: String, + val simd128: Boolean, + val threads: Boolean, + val crossOriginIsolated: Boolean, + val hardwareConcurrency: Int, + val residentWeightBytes: Long, + ) { + override fun toString(): String = + "mode=$mode simd128=$simd128 threads=$threads crossOriginIsolated=$crossOriginIsolated " + + "cores=$hardwareConcurrency residentWeightBytes=$residentWeightBytes" + } + + /** Current sidecar capabilities; `mode == "none"` before [initialize]. */ + public fun features(): SidecarFeatures = SidecarFeatures( + mode = modeName, + simd128 = isReady, + threads = modeName == "simd128-mt", + crossOriginIsolated = jsCrossOriginIsolated(), + hardwareConcurrency = jsHardwareConcurrency(), + residentWeightBytes = if (isReady) residentWeightBytes() else 0L, + ) } // ── JS glue ─────────────────────────────────────────────────────────────────────────────────────── @@ -260,3 +297,20 @@ private fun jsFp32Matmul(mod: JsAny, aPtr: Int, aStride: Int, bPtr: Int, bStride private fun jsFp32MatmulWt(mod: JsAny, inPtr: Int, wPtr: Int, outPtr: Int, m: Int, n: Int, k: Int): Unit = js("mod._skainet_fp32_matmul_wt(inPtr, 0, wPtr, 0, outPtr, 0, m, n, k)") + +private fun jsNarrowFloatMatmul(mod: JsAny, fnName: String, aPtr: Int, aStride: Int, bPtr: Int, bByteStride: Int, cPtr: Int, cStride: Int, m: Int, n: Int, k: Int): Unit = + js("mod[fnName](aPtr, 0, aStride, bPtr, 0, bByteStride, cPtr, 0, cStride, m, n, k)") + +private fun jsCrossOriginIsolated(): Boolean = js("typeof crossOriginIsolated !== 'undefined' && crossOriginIsolated === true") + +private fun jsHardwareConcurrency(): Int = js( + """ + (function() { + if (typeof navigator !== 'undefined' && typeof navigator.hardwareConcurrency === 'number') return navigator.hardwareConcurrency; + if (typeof process !== 'undefined' && process.versions != null && process.versions.node != null) { + try { return require('os').cpus().length; } catch (e) { return 0; } + } + return 0; + })() + """, +) diff --git a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmSimd.kt b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmSimd.kt index 9d9ac7ace..6038f5afd 100644 --- a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmSimd.kt +++ b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmSimd.kt @@ -28,8 +28,13 @@ public object WasmSimd { KernelDispatch.clearForTesting() WasmSimdKernelPack.install() WasmCpuOpsOverride.factory = { factory, schedule -> WasmCpuOps(factory, schedule) } + // The same one-line banner the JVM factory prints, so a console shows which tier runs. + println("[SKaiNET] Using SIMD128 sidecar kernels (${WasmKernels.features()})") } + /** What the installed sidecar runs on; `mode == "none"` when not installed. */ + public fun features(): WasmKernels.SidecarFeatures = WasmKernels.features() + /** Back to the scalar lane; frees every resident weight. Tests and model switching. */ public fun uninstall() { WasmCpuOpsOverride.factory = null diff --git a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt index 838302d87..ae1587591 100644 --- a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt +++ b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt @@ -2,8 +2,15 @@ package sk.ainet.exec.wasm import kotlinx.coroutines.test.runTest import sk.ainet.backend.api.kernel.KernelDispatch +import sk.ainet.backend.api.kernel.KernelRegistry +import sk.ainet.backend.api.kernel.KernelStrictness +import sk.ainet.backend.api.kernel.NoSuchKernelException import sk.ainet.context.DirectCpuExecutionContext +import sk.ainet.exec.kernel.ScalarBf16MatmulKernel +import sk.ainet.exec.kernel.ScalarFp16MatmulKernel import sk.ainet.exec.tensor.ops.DefaultCpuOps +import sk.ainet.lang.types.Bf16Codec +import sk.ainet.lang.types.Fp16Codec import sk.ainet.lang.tensor.Shape import sk.ainet.lang.tensor.Tensor import sk.ainet.lang.tensor.data.Q4_0Quantizer @@ -16,6 +23,7 @@ import kotlin.math.abs import kotlin.test.AfterTest import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFailsWith import kotlin.test.assertIs import kotlin.test.assertTrue @@ -65,11 +73,70 @@ class WasmSimdParityTest { fun `install swaps the ops and the sidecar reports a SIMD mode`() = runTest { val before = DirectCpuExecutionContext() assertIs(before.ops) + assertEquals("none", WasmKernels.features().mode) WasmSimd.install() assertTrue(WasmSimd.isInstalled) assertTrue(WasmKernels.mode.startsWith("simd128-"), WasmKernels.mode) val after = DirectCpuExecutionContext() assertIs(after.ops) + val f = WasmSimd.features() + assertEquals(WasmKernels.mode, f.mode) + assertTrue(f.simd128) + assertEquals(f.mode == "simd128-mt", f.threads) + assertTrue(f.hardwareConcurrency >= 1, "cores: ${f.hardwareConcurrency}") + } + + @Test + fun `BF16 and FP16 weights run on the sidecar and match the scalar kernels`() = runTest { + WasmSimd.install() + val provider = checkNotNull(KernelRegistry.bestAvailable()) + assertEquals("wasm-simd128", provider.name) + val m = 7; val n = 33; val k = 40 + val a = pseudo(m * k, 21) + val wf = pseudo(k * n, 23) + val bf16 = ByteArray(k * n * 2) + val fp16 = ByteArray(k * n * 2) + for (i in 0 until k * n) { + val b = Bf16Codec.encode(wf[i]); bf16[i * 2] = (b and 0xFF).toByte(); bf16[i * 2 + 1] = ((b ushr 8) and 0xFF).toByte() + val h = Fp16Codec.encode(wf[i]); fp16[i * 2] = (h and 0xFF).toByte(); fp16[i * 2 + 1] = ((h ushr 8) and 0xFF).toByte() + } + val refB = FloatArray(m * n); val refH = FloatArray(m * n) + ScalarBf16MatmulKernel.matmul(a, 0, k, bf16, 0, n * 2, refB, 0, n, m, n, k) + ScalarFp16MatmulKernel.matmul(a, 0, k, fp16, 0, n * 2, refH, 0, n, m, n, k) + val gotB = FloatArray(m * n); val gotH = FloatArray(m * n) + checkNotNull(provider.matmulBf16()).matmul(a, 0, k, bf16, 0, n * 2, gotB, 0, n, m, n, k) + checkNotNull(provider.matmulFp16()).matmul(a, 0, k, fp16, 0, n * 2, gotH, 0, n, m, n, k) + assertClose(refB, gotB, "bf16") + assertClose(refH, gotH, "fp16") + // A contiguous weight is resident after the first call; a strided window is staged per call. + assertTrue(WasmKernels.residentWeightBytes() >= 2L * k * n * 2) + val sub = FloatArray(m * 8) + val refSub = FloatArray(m * 8) + ScalarBf16MatmulKernel.matmul(a, 0, k, bf16, 4, n * 2, refSub, 0, 8, m, 8, k) + checkNotNull(provider.matmulBf16()).matmul(a, 0, k, bf16, 4, n * 2, sub, 0, 8, m, 8, k) + assertClose(refSub, sub, "bf16 window") + } + + @Test + fun `strict mode is honoured on wasm`() = runTest { + KernelStrictness.overrideEnabled = true + try { + assertTrue(KernelStrictness.isEnabled()) + val ctx = DirectCpuExecutionContext() + // Packed weight, no pack installed and the reference fallback forbidden: fail fast. + val w = q8(ctx, 64, 96, 5) + val x = ctx.fromFloatArray(Shape(2, 96), FP32::class, pseudo(2 * 96, 1)) + KernelDispatch.clearForTesting() + // A canonical row-major Q8_0 view has no exact scalar kernel (those are keyed input-block-major) + // and prepack is off by default here, so this is the reference-fallback site. + val out = sk.ainet.lang.memory.TensorView.dense(sk.ainet.lang.memory.Storage.Heap.floats(2 * 64), Shape(2, 64), sk.ainet.lang.types.FP32) + assertFailsWith { + KernelDispatch.matmul(x.data.view!!, w.data.view!!, out, sk.ainet.lang.memory.Scope.Ambient) + } + } finally { + KernelStrictness.overrideEnabled = null + } + assertEquals(false, KernelStrictness.isEnabled()) } @Test From f89bf511e277c0eb05c2dc6aa4c6295e3d62696d Mon Sep 17 00:00:00 2001 From: michalharakal Date: Mon, 19 Oct 2026 07:39:08 +0200 Subject: [PATCH 2/2] perf(kernels): SIMD128 bodies for K-quants, Q5_0/Q5_1 and dense FP32/BF16/FP16; threaded dense kernels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Explicit __wasm_simd128__ bodies for q4k, q5k, q6k, q5_0 and q5_1 (K-quant int8 dots on i32x4.dot_i16x8_s, Q5 fifth-bit plane via byte swizzle); helpers in skainet_simd.h next to the NEON ones. - Dense FP32 GEMM: 4x8 register-blocked, k-blocked SIMD128 micro-kernel; BF16/FP16 widen eight weights per step on SIMD128 and NEON (first NEON bodies for those formats). Accumulation order unchanged on every path. - skainet_fp32_matmul, skainet_bf16_matmul and skainet_fp16_matmul split the output over the shared row-thread pool like the packed kernels. - WasmCpuOps.matmul routes dense 2-D heap FP32 A·B to the sidecar GEMM. - Sidecar rebuilt; wasm parity tests for all seven packed formats and the ops-layer GEMM tile shapes; CHANGELOG and eager-execution docs. --- CHANGELOG.md | 3 + .../pages/explanation/eager-execution.adoc | 7 +- .../native/include/skainet_simd.h | 77 +++++- .../native/src/bf16_matmul.c | 210 ++++++++++++----- .../native/src/fp16_matmul.c | 223 +++++++++++++----- .../native/src/fp32_matmul.c | 184 ++++++++++++--- .../native/src/q4k_matmul.c | 25 +- .../native/src/q5_0_matmul.c | 24 ++ .../native/src/q5_1_matmul.c | 24 ++ .../native/src/q5k_matmul.c | 35 ++- .../native/src/q6k_matmul.c | 26 +- .../sk/ainet/exec/wasm/SidecarArtifacts.kt | 10 +- .../kotlin/sk/ainet/exec/wasm/WasmCpuOps.kt | 29 ++- .../sk/ainet/exec/wasm/WasmSimdParityTest.kt | 93 +++++++- 14 files changed, 804 insertions(+), 166 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63e4a7eef..77e38e8fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ - **`WasmSimd.features()` / `WasmKernels.features()`**: mode, SIMD128, threads, cross-origin isolation, logical cores and resident weight bytes — the wasm counterpart of the JVM provider banner. `WasmSimd.install()` prints one `[SKaiNET] Using SIMD128 sidecar kernels (…)` line like the JVM factory does. - **`KernelStrictness` is common code** (was JVM-only): `KernelStrictness.overrideEnabled` is the programmatic switch on every target; the JVM and Android still read `-Dskainet.strict.kernels`. `KernelDispatch` fails fast before the decoding reference fallback and `DefaultCpuOps.matmul` before the generic per-element loop, so strict mode means the same thing on every tier. - **Kernel support matrix**: a `Float16` row, BF16/FP16 in the wasm column, Q6_K corrected to `native-ffm` on the JVM (the provider has had the kernel; the declared tier had not), and a third table, *Resident serving*, naming the sidecar-resident weights that stand in for mapped serving on JS/WASM. `KernelSupportMatrixTest` now gates the declared Panama and FFM tiers against what the providers expose. +- **Explicit SIMD128 bodies for every sidecar matmul kernel**: Q4_K, Q5_K, Q6_K, Q5_0 and Q5_1 join Q8_0 and Q4_0 with hand-written `__wasm_simd128__` paths (the K-quant int8 dots on `i32x4.dot_i16x8_s`, the Q5 fifth-bit plane via a byte swizzle); the dense FP32 GEMM gets a 4×8 register-blocked, k-blocked micro-kernel; BF16 and FP16 widen eight weights per step. BF16 and FP16 also gain NEON bodies (none existed on any tier). Results stay bit-identical in accumulation order to the portable bodies. +- **Threaded dense kernels**: `skainet_fp32_matmul`, `skainet_bf16_matmul` and `skainet_fp16_matmul` now split the output over the shared row-thread pool like the packed kernels do (the GEMM over the longer side of `C`, the 16-bit kernels over columns) — the mt sidecar's pthreads in a browser, the native pool on the JVM. +- **`WasmCpuOps.matmul`**: a dense 2-D `A · B` on heap FP32 operands runs the sidecar GEMM; the common `[k, n]` loop no longer serves that shape on wasm (it was the only dense path that never reached the sidecar). - **`wasm-bench` runs the `engine-*` scenarios** of the JVM publish harness (`engine-fp32-gemm`, `engine-kernel-matmul`, `engine-bf16-matmul`, `engine-q8-matmul`, `engine-q4-gemm`, `engine-ternary-f32-gemv`, `engine-elementwise-add`, `engine-reductions-sum/mean`) with identical shapes and metrics on every tier it measures, so the JVM and wasm numbers sit in one table. ## [0.61.0] - 2026-10-16 diff --git a/docs/modules/ROOT/pages/explanation/eager-execution.adoc b/docs/modules/ROOT/pages/explanation/eager-execution.adoc index ff94753b2..f251bfbe6 100644 --- a/docs/modules/ROOT/pages/explanation/eager-execution.adoc +++ b/docs/modules/ROOT/pages/explanation/eager-execution.adoc @@ -75,9 +75,10 @@ Resolution is by priority: *Native (100 — whichever of FFM/JNI/cinterop applie Panama / Wasm SIMD128 (50) → Scalar (0)*. The best *available* provider that carries the kernel wins; otherwise it cascades down. At most one native tier is compiled into a given target, so the native columns are mutually exclusive per platform rather than stacked. The Wasm SIMD128 column is the -sidecar pack (`skainet-backend-wasm-simd`), present only after `WasmSimd.install()`; the explicit -SIMD128 bodies are Q8_0, Q4_0 and dense `x · Wᵀ`, the other formats run the portable C body -auto-vectorised by Emscripten. +sidecar pack (`skainet-backend-wasm-simd`), present only after `WasmSimd.install()`; every matmul +kernel in it has an explicit SIMD128 body (the K-quant int8 dots on `i32x4.dot_i16x8_s`, a 4×8 +register-blocked dense GEMM, eight-wide BF16/FP16 widening), and the dense kernels thread over the +sidecar's pthread pool like the packed ones when the page is cross-origin isolated. Packed weights reach a kernel through the registry by declaring their xref:explanation/packed-weight-layout.adoc[block order]; a canonical weight is relayouted once, diff --git a/skainet-backends/skainet-backend-native-cpu/native/include/skainet_simd.h b/skainet-backends/skainet-backend-native-cpu/native/include/skainet_simd.h index 0b4fd618f..b90d3c1d7 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/include/skainet_simd.h +++ b/skainet-backends/skainet-backend-native-cpu/native/include/skainet_simd.h @@ -37,8 +37,9 @@ /* WebAssembly SIMD128 (SKEEP-007 Tier 1): the browser sidecar is built with * `emcc -msimd128`, which defines __wasm_simd128__. Kernels that have an explicit * SIMD128 body select it with `#elif defined(__wasm_simd128__)` between their NEON - * and portable branches; the rest rely on clang's auto-vectoriser over the - * portable body. */ + * and portable branches. Every matmul kernel in the sidecar build has one + * (q8_0, q4_0, q4k, q5k, q6k, q5_0, q5_1, fp32, fp32_wt, bf16, fp16); the helpers + * below are the SIMD128 counterparts of the NEON ones above. */ #if defined(__wasm_simd128__) # include # define SKAINET_HAVE_WASM_SIMD128 1 @@ -93,4 +94,76 @@ static inline void skainet_neon_u8x16_to_f32x4x4(uint8x16_t v, float32x4_t out[4 } #endif +#ifdef SKAINET_HAVE_WASM_SIMD128 +/* Horizontal sum of an f32x4 lane vector. */ +static inline float skainet_wasm_hadd_f32(v128_t v) { + return wasm_f32x4_extract_lane(v, 0) + wasm_f32x4_extract_lane(v, 1) + + wasm_f32x4_extract_lane(v, 2) + wasm_f32x4_extract_lane(v, 3); +} + +/* Horizontal sum of an i32x4 lane vector. */ +static inline int32_t skainet_wasm_hadd_i32(v128_t v) { + return wasm_i32x4_extract_lane(v, 0) + wasm_i32x4_extract_lane(v, 1) + + wasm_i32x4_extract_lane(v, 2) + wasm_i32x4_extract_lane(v, 3); +} + +/* + * 16 × (int8 · int8) → i32x4 partial sums: the SIMD128 stand-in for NEON's + * vdotq_s32. Both operands widen to i16x8 halves and `i32x4.dot_i16x8_s` + * multiplies lane pairs and adds them, so each i32 lane holds four products. + * Exact for any int8 inputs (|product| ≤ 2^14, four of them fit an i32). + */ +static inline v128_t skainet_wasm_dot_i8x16(v128_t a, v128_t b) { + const v128_t lo = wasm_i32x4_dot_i16x8(wasm_i16x8_extend_low_i8x16(a), + wasm_i16x8_extend_low_i8x16(b)); + const v128_t hi = wasm_i32x4_dot_i16x8(wasm_i16x8_extend_high_i8x16(a), + wasm_i16x8_extend_high_i8x16(b)); + return wasm_i32x4_add(lo, hi); +} + +/* Same for an UNSIGNED 8-bit left operand (quant codes 0..31) against int8. */ +static inline v128_t skainet_wasm_dot_u8x16_i8x16(v128_t codes, v128_t a) { + const v128_t lo = wasm_i32x4_dot_i16x8(wasm_u16x8_extend_low_u8x16(codes), + wasm_i16x8_extend_low_i8x16(a)); + const v128_t hi = wasm_i32x4_dot_i16x8(wasm_u16x8_extend_high_u8x16(codes), + wasm_i16x8_extend_high_i8x16(a)); + return wasm_i32x4_add(lo, hi); +} + +/* Σ of 16 int8 lanes as i32x4 partial sums (pairwise widening adds). */ +static inline v128_t skainet_wasm_sum_i8x16(v128_t a) { + return wasm_i32x4_extadd_pairwise_i16x8(wasm_i16x8_extadd_pairwise_i8x16(a)); +} + +/* Widen 16 unsigned bytes to four f32x4 lanes (out[0] = lanes 0..3, …). */ +static inline void skainet_wasm_u8x16_to_f32x4x4(v128_t v, v128_t out[4]) { + const v128_t lo16 = wasm_u16x8_extend_low_u8x16(v); + const v128_t hi16 = wasm_u16x8_extend_high_u8x16(v); + out[0] = wasm_f32x4_convert_i32x4(wasm_u32x4_extend_low_u16x8(lo16)); + out[1] = wasm_f32x4_convert_i32x4(wasm_u32x4_extend_high_u16x8(lo16)); + out[2] = wasm_f32x4_convert_i32x4(wasm_u32x4_extend_low_u16x8(hi16)); + out[3] = wasm_f32x4_convert_i32x4(wasm_u32x4_extend_high_u16x8(hi16)); +} + +/* + * Expand the 32-bit high-bit plane of a Q5_0/Q5_1 block into two u8x16 masks + * holding 0x10 where element j (lo: 0..15, hi: 16..31) has its fifth bit set: + * broadcast each `qh` byte to its eight lanes with a swizzle, test the per-lane + * bit and turn the compare mask into the code value 16. + */ +static inline void skainet_wasm_q5_fifth_bits(uint32_t qh32, v128_t* fifth_lo, v128_t* fifth_hi) { + const v128_t bytes = wasm_i32x4_splat((int32_t) qh32); + const v128_t idx_lo = wasm_i8x16_const(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1); + const v128_t idx_hi = wasm_i8x16_const(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3); + const v128_t bitmask = wasm_i8x16_const(1, 2, 4, 8, 16, 32, 64, (int8_t) 0x80, + 1, 2, 4, 8, 16, 32, 64, (int8_t) 0x80); + const v128_t sixteen = wasm_i8x16_splat(0x10); + const v128_t zero = wasm_i8x16_splat(0); + const v128_t lo = wasm_v128_and(wasm_i8x16_swizzle(bytes, idx_lo), bitmask); + const v128_t hi = wasm_v128_and(wasm_i8x16_swizzle(bytes, idx_hi), bitmask); + *fifth_lo = wasm_v128_and(wasm_i8x16_ne(lo, zero), sixteen); + *fifth_hi = wasm_v128_and(wasm_i8x16_ne(hi, zero), sixteen); +} +#endif + #endif /* SKAINET_SIMD_H */ diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/bf16_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/bf16_matmul.c index 923a42c82..9c5dd47aa 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/bf16_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/bf16_matmul.c @@ -1,4 +1,6 @@ #include "skainet_kernels.h" +#include "skainet_simd.h" +#include "skainet_row_threads.h" #include #include @@ -25,9 +27,8 @@ * * At m == 1 it is plain i-p-j (outer-product into the single row of C). The * inner `c[j] += a_ip * bf16_to_float(b[j])` loop streams two contiguous - * arrays — auto-vectorizes under -O3 -ffast-math into vfmadd231ps (x86_64) / - * fmla (AArch64). Every B element is used exactly once, so there is nothing to - * reuse and sequential streaming is the right shape. + * arrays. Every B element is used exactly once, so there is nothing to reuse + * and sequential streaming is the right shape. * * At m > 1, i-p-j walks the whole of B once per row of A. For ffn_up 8B at * m=16 that is 16 passes over 90 MiB, and the kernel is bandwidth-bound long @@ -37,13 +38,24 @@ * times. The tile is sized so the widened row and the m C rows it feeds stay * resident together. * - * Accumulation order into any given C element is p ascending on both paths, so - * the two are bit-identical to each other and to the original i-p-j - * formulation, not merely close. + * SIMD bodies (NEON on AArch64, SIMD128 in the Emscripten sidecar) widen eight + * BF16 values per step — unpack to 32-bit lanes, shift left 16 — and + * multiply-add four lanes at a time, both on the m == 1 stream and on the + * tile; the portable body is the scalar form of the same loops. * - * On ARMv8.6-A+ a future pass can swap the scalar dequant for a - * `bfdot`/`bfmmla` intrinsic kernel; that lives behind a runtime feature check - * and is out of scope here. + * Accumulation order into any given C element is p ascending on every path, + * so they are bit-identical to each other and to the original i-p-j + * formulation, not merely close (the NEON path uses a fused multiply-add, + * as the auto-vectorised portable body does under -ffast-math on AArch64). + * + * Threading (#1195 pattern): the columns of C are split into disjoint ranges + * through skainet_row_threads.h when n is large enough; each worker runs the + * whole m × k work for its columns, so no accumulation order changes. On + * Emscripten that is the pthread pool of the mt sidecar. + * + * On ARMv8.6-A+ a future pass can swap the shift for a `bfdot`/`bfmmla` + * intrinsic kernel; that lives behind a runtime feature check and is out of + * scope here. * * Caller contract (mirrors skainet_fp32_matmul): * - C is FULLY OVERWRITTEN in the m×n block. @@ -58,71 +70,151 @@ */ #define SKAINET_BF16_TILE 512 -SKAINET_API void skainet_bf16_matmul( - const float* SKAINET_RESTRICT a, int32_t a_offset, int32_t a_stride, - const uint8_t* SKAINET_RESTRICT b, int32_t b_byte_offset, int32_t b_byte_stride, - float* SKAINET_RESTRICT c, int32_t c_offset, int32_t c_stride, - int32_t m, int32_t n, int32_t k +static inline float skainet_bf16_to_float(const uint8_t* SKAINET_RESTRICT src) { + /* Read 2 bytes LE. memcpy is strict-aliasing safe and the compiler folds + * it to a single 16-bit load. */ + uint16_t bits; + memcpy(&bits, src, sizeof(uint16_t)); + const uint32_t fp32_bits = ((uint32_t) bits) << 16; + float f; + memcpy(&f, &fp32_bits, sizeof(float)); + return f; +} + +/* + * c[0..count) += a_ip * bf16(src[0..count)) — the m == 1 stream; and + * dst[0..count) = bf16(src[0..count)) — the tile widen. Eight values per SIMD + * step, scalar tail. + */ +static inline void skainet_bf16_stream_axpy( + float* SKAINET_RESTRICT c, const uint8_t* SKAINET_RESTRICT src, float a_ip, int32_t count ) { - if (m <= 0 || n <= 0) return; + int32_t j = 0; +#if defined(SKAINET_HAVE_NEON) + const float32x4_t va = vdupq_n_f32(a_ip); + for (; j + 8 <= count; j += 8) { + const uint16x8_t v = vreinterpretq_u16_u8(vld1q_u8(src + (size_t) j * 2)); + const float32x4_t lo = vreinterpretq_f32_u32(vshlq_n_u32(vmovl_u16(vget_low_u16(v)), 16)); + const float32x4_t hi = vreinterpretq_f32_u32(vshlq_n_u32(vmovl_u16(vget_high_u16(v)), 16)); + vst1q_f32(c + j, vfmaq_f32(vld1q_f32(c + j), va, lo)); + vst1q_f32(c + j + 4, vfmaq_f32(vld1q_f32(c + j + 4), va, hi)); + } +#elif defined(SKAINET_HAVE_WASM_SIMD128) + const v128_t va = wasm_f32x4_splat(a_ip); + for (; j + 8 <= count; j += 8) { + const v128_t v = wasm_v128_load(src + (size_t) j * 2); + const v128_t lo = wasm_i32x4_shl(wasm_u32x4_extend_low_u16x8(v), 16); + const v128_t hi = wasm_i32x4_shl(wasm_u32x4_extend_high_u16x8(v), 16); + wasm_v128_store(c + j, wasm_f32x4_add(wasm_v128_load(c + j), wasm_f32x4_mul(va, lo))); + wasm_v128_store(c + j + 4, wasm_f32x4_add(wasm_v128_load(c + j + 4), wasm_f32x4_mul(va, hi))); + } +#endif + for (; j < count; ++j) c[j] += a_ip * skainet_bf16_to_float(src + (size_t) j * 2); +} + +static inline void skainet_bf16_widen( + float* SKAINET_RESTRICT dst, const uint8_t* SKAINET_RESTRICT src, int32_t count +) { + int32_t j = 0; +#if defined(SKAINET_HAVE_NEON) + for (; j + 8 <= count; j += 8) { + const uint16x8_t v = vreinterpretq_u16_u8(vld1q_u8(src + (size_t) j * 2)); + vst1q_f32(dst + j, vreinterpretq_f32_u32(vshlq_n_u32(vmovl_u16(vget_low_u16(v)), 16))); + vst1q_f32(dst + j + 4, vreinterpretq_f32_u32(vshlq_n_u32(vmovl_u16(vget_high_u16(v)), 16))); + } +#elif defined(SKAINET_HAVE_WASM_SIMD128) + for (; j + 8 <= count; j += 8) { + const v128_t v = wasm_v128_load(src + (size_t) j * 2); + wasm_v128_store(dst + j, wasm_i32x4_shl(wasm_u32x4_extend_low_u16x8(v), 16)); + wasm_v128_store(dst + j + 4, wasm_i32x4_shl(wasm_u32x4_extend_high_u16x8(v), 16)); + } +#endif + for (; j < count; ++j) dst[j] = skainet_bf16_to_float(src + (size_t) j * 2); +} + +/* c[0..count) += a_ip * w[0..count) on the widened tile. */ +static inline void skainet_f32_axpy( + float* SKAINET_RESTRICT c, const float* SKAINET_RESTRICT w, float a_ip, int32_t count +) { + int32_t j = 0; +#if defined(SKAINET_HAVE_NEON) + const float32x4_t va = vdupq_n_f32(a_ip); + for (; j + 4 <= count; j += 4) vst1q_f32(c + j, vfmaq_f32(vld1q_f32(c + j), va, vld1q_f32(w + j))); +#elif defined(SKAINET_HAVE_WASM_SIMD128) + const v128_t va = wasm_f32x4_splat(a_ip); + for (; j + 4 <= count; j += 4) { + wasm_v128_store(c + j, wasm_f32x4_add(wasm_v128_load(c + j), wasm_f32x4_mul(va, wasm_v128_load(w + j)))); + } +#endif + for (; j < count; ++j) c[j] += a_ip * w[j]; +} + +typedef struct { + const float* a; /* a + a_offset */ + const uint8_t* b; /* b + b_byte_offset */ + float* c; /* c + c_offset */ + int32_t a_stride, b_byte_stride, c_stride; + int32_t m, n, k; +} skainet_bf16_ctx; + +/* Columns [j0, j1) of C, all rows. */ +static void skainet_bf16_columns(void* vctx, int32_t j0, int32_t j1) { + const skainet_bf16_ctx* c = (const skainet_bf16_ctx*) vctx; /* Zero the output block. Required by the SPI for k == 0 AND a - * prerequisite for the i-p-j accumulator below. */ - for (int32_t i = 0; i < m; ++i) { - float* SKAINET_RESTRICT c_row = c + c_offset + (size_t) i * c_stride; - for (int32_t j = 0; j < n; ++j) { - c_row[j] = 0.0f; - } + * prerequisite for the accumulators below. */ + for (int32_t i = 0; i < c->m; ++i) { + float* SKAINET_RESTRICT c_row = c->c + (size_t) i * c->c_stride; + for (int32_t j = j0; j < j1; ++j) c_row[j] = 0.0f; } - if (k <= 0) return; - - if (m == 1) { - const float* SKAINET_RESTRICT a_row = a + a_offset; - float* SKAINET_RESTRICT c_row = c + c_offset; - for (int32_t p = 0; p < k; ++p) { - const float a_ip = a_row[p]; - const uint8_t* SKAINET_RESTRICT b_row = - b + b_byte_offset + (size_t) p * b_byte_stride; - for (int32_t j = 0; j < n; ++j) { - /* Read 2 bytes LE. memcpy is strict-aliasing safe and the - * compiler folds it to a single 16-bit load. */ - uint16_t bits; - memcpy(&bits, b_row + (size_t) j * 2, sizeof(uint16_t)); - uint32_t fp32_bits = ((uint32_t) bits) << 16; - float b_pj; - memcpy(&b_pj, &fp32_bits, sizeof(float)); - c_row[j] += a_ip * b_pj; - } + if (c->k <= 0) return; + + if (c->m == 1) { + const float* SKAINET_RESTRICT a_row = c->a; + float* SKAINET_RESTRICT c_row = c->c + j0; + for (int32_t p = 0; p < c->k; ++p) { + const uint8_t* SKAINET_RESTRICT b_row = c->b + (size_t) p * c->b_byte_stride + (size_t) j0 * 2; + skainet_bf16_stream_axpy(c_row, b_row, a_row[p], j1 - j0); } return; } float widened[SKAINET_BF16_TILE]; - for (int32_t j0 = 0; j0 < n; j0 += SKAINET_BF16_TILE) { - const int32_t tile = - (n - j0) < SKAINET_BF16_TILE ? (n - j0) : SKAINET_BF16_TILE; + for (int32_t t0 = j0; t0 < j1; t0 += SKAINET_BF16_TILE) { + const int32_t tile = (j1 - t0) < SKAINET_BF16_TILE ? (j1 - t0) : SKAINET_BF16_TILE; - for (int32_t p = 0; p < k; ++p) { - const uint8_t* SKAINET_RESTRICT b_row = - b + b_byte_offset + (size_t) p * b_byte_stride + (size_t) j0 * 2; + for (int32_t p = 0; p < c->k; ++p) { + const uint8_t* SKAINET_RESTRICT b_row = c->b + (size_t) p * c->b_byte_stride + (size_t) t0 * 2; /* Widen this row's tile once, for all m rows of C below. */ - for (int32_t j = 0; j < tile; ++j) { - uint16_t bits; - memcpy(&bits, b_row + (size_t) j * 2, sizeof(uint16_t)); - uint32_t fp32_bits = ((uint32_t) bits) << 16; - memcpy(&widened[j], &fp32_bits, sizeof(float)); - } + skainet_bf16_widen(widened, b_row, tile); - for (int32_t i = 0; i < m; ++i) { - const float a_ip = a[a_offset + (size_t) i * a_stride + p]; - float* SKAINET_RESTRICT c_row = - c + c_offset + (size_t) i * c_stride + j0; - for (int32_t j = 0; j < tile; ++j) { - c_row[j] += a_ip * widened[j]; - } + for (int32_t i = 0; i < c->m; ++i) { + const float a_ip = c->a[(size_t) i * c->a_stride + p]; + float* SKAINET_RESTRICT c_row = c->c + (size_t) i * c->c_stride + t0; + skainet_f32_axpy(c_row, widened, a_ip, tile); } } } } + +SKAINET_API void skainet_bf16_matmul( + const float* SKAINET_RESTRICT a, int32_t a_offset, int32_t a_stride, + const uint8_t* SKAINET_RESTRICT b, int32_t b_byte_offset, int32_t b_byte_stride, + float* SKAINET_RESTRICT c, int32_t c_offset, int32_t c_stride, + int32_t m, int32_t n, int32_t k +) { + if (m <= 0 || n <= 0) return; + skainet_bf16_ctx ctx; + ctx.a = a + a_offset; + ctx.b = b + b_byte_offset; + ctx.c = c + c_offset; + ctx.a_stride = a_stride; + ctx.b_byte_stride = b_byte_stride; + ctx.c_stride = c_stride; + ctx.m = m; + ctx.n = n; + ctx.k = k < 0 ? 0 : k; + skainet_run_rows(skainet_bf16_columns, &ctx, n); +} diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/fp16_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/fp16_matmul.c index 54297d6b8..1d77f0e3d 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/fp16_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/fp16_matmul.c @@ -1,4 +1,6 @@ #include "skainet_kernels.h" +#include "skainet_simd.h" +#include "skainet_row_threads.h" #include #include @@ -23,14 +25,14 @@ * fp16_to_float below is branch-free: the two special cases are folded in * with arithmetic masks, which keeps the inner loop a straight-line sequence * the vectorizer can widen (unpack to 32-bit lanes, integer ops, one FMA). + * The SIMD128 body is that same sequence on i32x4 lanes, so it decodes + * bit-for-bit what the scalar does; the NEON body uses the ISA's own + * binary16 → binary32 convert (base AArch64, exact for every input). * - * Deliberately *not* using _Float16 or F16C intrinsics. The x86_64 build - * carries no -march flag, so F16C cannot be assumed, and _Float16 without it - * lowers to libgcc helper calls that are slower than this and block - * vectorization outright. AArch64 does build with +fp16, but a second code - * path would double the surface to test for a conversion that is already a - * handful of integer ops. Runtime ISA dispatch is the place for that, if it - * ever pays for itself. + * Deliberately *not* using _Float16 or F16C intrinsics on x86. The x86_64 + * build carries no -march flag, so F16C cannot be assumed, and _Float16 + * without it lowers to libgcc helper calls that are slower than this and + * block vectorization outright. * * Iteration order depends on m. * @@ -46,19 +48,25 @@ * decode count drops from m*k*n to k*n. The tile is sized so the decoded row * and the m C rows it feeds stay resident together. * - * Accumulation order into any given C element is p ascending on both paths, so - * the two are bit-identical to each other and to the original i-p-j + * Accumulation order into any given C element is p ascending on every path, + * so they are bit-identical to each other and to the original i-p-j * formulation, not merely close. * + * Threading (#1195 pattern): the columns of C are split into disjoint ranges + * through skainet_row_threads.h when n is large enough; each worker runs the + * whole m × k work for its columns, so no accumulation order changes. On + * Emscripten that is the pthread pool of the mt sidecar. + * * Caller contract (mirrors skainet_bf16_matmul): * - C is FULLY OVERWRITTEN in the m×n block. * - k == 0 zeros the m×n block. * - m == 0 || n == 0 is a no-op. * - Negative m / n / k are caller errors; defensively treated as no-op. * - * NaN note: a signaling binary16 NaN stays signaling here, matching the JVM - * Panama kernel. It is not observable — the value is immediately multiplied, - * and that quiets it. + * NaN note: a signaling binary16 NaN stays signaling on the scalar and + * SIMD128 paths, matching the JVM Panama kernel; the NEON convert quiets it. + * Neither is observable — the value is immediately multiplied, and that + * quiets it anyway. */ /* binary16's exponent field once shifted into FP32 position (0x7C00 << 13). */ @@ -110,70 +118,163 @@ static inline float skainet_fp16_to_float(uint16_t h) { return out; } -SKAINET_API void skainet_fp16_matmul( - const float* SKAINET_RESTRICT a, int32_t a_offset, int32_t a_stride, - const uint8_t* SKAINET_RESTRICT b, int32_t b_byte_offset, int32_t b_byte_stride, - float* SKAINET_RESTRICT c, int32_t c_offset, int32_t c_stride, - int32_t m, int32_t n, int32_t k +static inline float skainet_fp16_load(const uint8_t* SKAINET_RESTRICT src) { + /* Read 2 bytes LE. memcpy is strict-aliasing safe and the compiler folds + * it to a single 16-bit load. */ + uint16_t bits; + memcpy(&bits, src, sizeof(uint16_t)); + return skainet_fp16_to_float(bits); +} + +#if defined(SKAINET_HAVE_WASM_SIMD128) +/* The branch-free scalar conversion on four u32 lanes holding binary16 bits. */ +static inline v128_t skainet_fp16x4_to_f32x4(v128_t bits) { + const v128_t exp_mask = wasm_i32x4_splat((int32_t) SKAINET_FP16_EXP_FIELD); + const v128_t rebias = wasm_i32x4_splat((int32_t) SKAINET_FP16_REBIAS); + const v128_t sign = wasm_i32x4_shl(wasm_v128_and(bits, wasm_i32x4_splat(0x8000)), 16); + const v128_t shifted = wasm_i32x4_shl(wasm_v128_and(bits, wasm_i32x4_splat(0x7FFF)), 13); + const v128_t exp_field = wasm_v128_and(shifted, exp_mask); + const v128_t is_inf_nan = wasm_i32x4_eq(exp_field, exp_mask); + const v128_t is_subnormal = wasm_i32x4_eq(exp_field, wasm_i32x4_splat(0)); + const v128_t biased = wasm_i32x4_add(wasm_i32x4_add(shifted, rebias), wasm_v128_and(rebias, is_inf_nan)); + const v128_t bumped = wasm_i32x4_add(biased, wasm_i32x4_splat((int32_t) SKAINET_FP16_SUBNORMAL_BUMP)); + const v128_t renormalized = wasm_f32x4_sub(bumped, wasm_f32x4_splat(0x1p-14f)); + const v128_t magnitude = wasm_v128_bitselect(renormalized, biased, is_subnormal); + return wasm_v128_or(sign, magnitude); +} +#endif + +/* c[0..count) += a_ip * fp16(src[0..count)) — the m == 1 stream. Eight values per SIMD step, scalar tail. */ +static inline void skainet_fp16_stream_axpy( + float* SKAINET_RESTRICT c, const uint8_t* SKAINET_RESTRICT src, float a_ip, int32_t count ) { - if (m <= 0 || n <= 0) return; + int32_t j = 0; +#if defined(SKAINET_HAVE_NEON) + const float32x4_t va = vdupq_n_f32(a_ip); + for (; j + 8 <= count; j += 8) { + const uint16x8_t v = vreinterpretq_u16_u8(vld1q_u8(src + (size_t) j * 2)); + const float32x4_t lo = vcvt_f32_f16(vreinterpret_f16_u16(vget_low_u16(v))); + const float32x4_t hi = vcvt_f32_f16(vreinterpret_f16_u16(vget_high_u16(v))); + vst1q_f32(c + j, vfmaq_f32(vld1q_f32(c + j), va, lo)); + vst1q_f32(c + j + 4, vfmaq_f32(vld1q_f32(c + j + 4), va, hi)); + } +#elif defined(SKAINET_HAVE_WASM_SIMD128) + const v128_t va = wasm_f32x4_splat(a_ip); + for (; j + 8 <= count; j += 8) { + const v128_t v = wasm_v128_load(src + (size_t) j * 2); + const v128_t lo = skainet_fp16x4_to_f32x4(wasm_u32x4_extend_low_u16x8(v)); + const v128_t hi = skainet_fp16x4_to_f32x4(wasm_u32x4_extend_high_u16x8(v)); + wasm_v128_store(c + j, wasm_f32x4_add(wasm_v128_load(c + j), wasm_f32x4_mul(va, lo))); + wasm_v128_store(c + j + 4, wasm_f32x4_add(wasm_v128_load(c + j + 4), wasm_f32x4_mul(va, hi))); + } +#endif + for (; j < count; ++j) c[j] += a_ip * skainet_fp16_load(src + (size_t) j * 2); +} + +/* dst[0..count) = fp16(src[0..count)) — the tile decode. */ +static inline void skainet_fp16_widen( + float* SKAINET_RESTRICT dst, const uint8_t* SKAINET_RESTRICT src, int32_t count +) { + int32_t j = 0; +#if defined(SKAINET_HAVE_NEON) + for (; j + 8 <= count; j += 8) { + const uint16x8_t v = vreinterpretq_u16_u8(vld1q_u8(src + (size_t) j * 2)); + vst1q_f32(dst + j, vcvt_f32_f16(vreinterpret_f16_u16(vget_low_u16(v)))); + vst1q_f32(dst + j + 4, vcvt_f32_f16(vreinterpret_f16_u16(vget_high_u16(v)))); + } +#elif defined(SKAINET_HAVE_WASM_SIMD128) + for (; j + 8 <= count; j += 8) { + const v128_t v = wasm_v128_load(src + (size_t) j * 2); + wasm_v128_store(dst + j, skainet_fp16x4_to_f32x4(wasm_u32x4_extend_low_u16x8(v))); + wasm_v128_store(dst + j + 4, skainet_fp16x4_to_f32x4(wasm_u32x4_extend_high_u16x8(v))); + } +#endif + for (; j < count; ++j) dst[j] = skainet_fp16_load(src + (size_t) j * 2); +} + +/* c[0..count) += a_ip * w[0..count) on the decoded tile. */ +static inline void skainet_f32_axpy( + float* SKAINET_RESTRICT c, const float* SKAINET_RESTRICT w, float a_ip, int32_t count +) { + int32_t j = 0; +#if defined(SKAINET_HAVE_NEON) + const float32x4_t va = vdupq_n_f32(a_ip); + for (; j + 4 <= count; j += 4) vst1q_f32(c + j, vfmaq_f32(vld1q_f32(c + j), va, vld1q_f32(w + j))); +#elif defined(SKAINET_HAVE_WASM_SIMD128) + const v128_t va = wasm_f32x4_splat(a_ip); + for (; j + 4 <= count; j += 4) { + wasm_v128_store(c + j, wasm_f32x4_add(wasm_v128_load(c + j), wasm_f32x4_mul(va, wasm_v128_load(w + j)))); + } +#endif + for (; j < count; ++j) c[j] += a_ip * w[j]; +} + +typedef struct { + const float* a; /* a + a_offset */ + const uint8_t* b; /* b + b_byte_offset */ + float* c; /* c + c_offset */ + int32_t a_stride, b_byte_stride, c_stride; + int32_t m, n, k; +} skainet_fp16_ctx; + +/* Columns [j0, j1) of C, all rows. */ +static void skainet_fp16_columns(void* vctx, int32_t j0, int32_t j1) { + const skainet_fp16_ctx* c = (const skainet_fp16_ctx*) vctx; /* Zero the output block. Required by the SPI for k == 0 AND a - * prerequisite for the i-p-j accumulator below. */ - for (int32_t i = 0; i < m; ++i) { - float* SKAINET_RESTRICT c_row = c + c_offset + (size_t) i * c_stride; - for (int32_t j = 0; j < n; ++j) { - c_row[j] = 0.0f; - } + * prerequisite for the accumulators below. */ + for (int32_t i = 0; i < c->m; ++i) { + float* SKAINET_RESTRICT c_row = c->c + (size_t) i * c->c_stride; + for (int32_t j = j0; j < j1; ++j) c_row[j] = 0.0f; } - if (k <= 0) return; - - if (m == 1) { - const float* SKAINET_RESTRICT a_row = a + a_offset; - float* SKAINET_RESTRICT c_row = c + c_offset; - for (int32_t p = 0; p < k; ++p) { - const float a_ip = a_row[p]; - const uint8_t* SKAINET_RESTRICT b_row = - b + b_byte_offset + (size_t) p * b_byte_stride; - for (int32_t j = 0; j < n; ++j) { - /* Read 2 bytes LE. memcpy is strict-aliasing safe and the - * compiler folds it to a single 16-bit load. */ - uint16_t bits; - memcpy(&bits, b_row + (size_t) j * 2, sizeof(uint16_t)); - c_row[j] += a_ip * skainet_fp16_to_float(bits); - } + if (c->k <= 0) return; + + if (c->m == 1) { + const float* SKAINET_RESTRICT a_row = c->a; + float* SKAINET_RESTRICT c_row = c->c + j0; + for (int32_t p = 0; p < c->k; ++p) { + const uint8_t* SKAINET_RESTRICT b_row = c->b + (size_t) p * c->b_byte_stride + (size_t) j0 * 2; + skainet_fp16_stream_axpy(c_row, b_row, a_row[p], j1 - j0); } return; } float decoded[SKAINET_FP16_TILE]; - for (int32_t j0 = 0; j0 < n; j0 += SKAINET_FP16_TILE) { - const int32_t tile = - (n - j0) < SKAINET_FP16_TILE ? (n - j0) : SKAINET_FP16_TILE; + for (int32_t t0 = j0; t0 < j1; t0 += SKAINET_FP16_TILE) { + const int32_t tile = (j1 - t0) < SKAINET_FP16_TILE ? (j1 - t0) : SKAINET_FP16_TILE; - for (int32_t p = 0; p < k; ++p) { - const uint8_t* SKAINET_RESTRICT b_row = - b + b_byte_offset + (size_t) p * b_byte_stride + (size_t) j0 * 2; + for (int32_t p = 0; p < c->k; ++p) { + const uint8_t* SKAINET_RESTRICT b_row = c->b + (size_t) p * c->b_byte_stride + (size_t) t0 * 2; /* Decode this row's tile once, for all m rows of C below. */ - for (int32_t j = 0; j < tile; ++j) { - /* Read 2 bytes LE. memcpy is strict-aliasing safe and the - * compiler folds it to a single 16-bit load. */ - uint16_t bits; - memcpy(&bits, b_row + (size_t) j * 2, sizeof(uint16_t)); - decoded[j] = skainet_fp16_to_float(bits); - } + skainet_fp16_widen(decoded, b_row, tile); - for (int32_t i = 0; i < m; ++i) { - const float a_ip = - a[a_offset + (size_t) i * a_stride + p]; - float* SKAINET_RESTRICT c_row = - c + c_offset + (size_t) i * c_stride + j0; - for (int32_t j = 0; j < tile; ++j) { - c_row[j] += a_ip * decoded[j]; - } + for (int32_t i = 0; i < c->m; ++i) { + const float a_ip = c->a[(size_t) i * c->a_stride + p]; + float* SKAINET_RESTRICT c_row = c->c + (size_t) i * c->c_stride + t0; + skainet_f32_axpy(c_row, decoded, a_ip, tile); } } } } + +SKAINET_API void skainet_fp16_matmul( + const float* SKAINET_RESTRICT a, int32_t a_offset, int32_t a_stride, + const uint8_t* SKAINET_RESTRICT b, int32_t b_byte_offset, int32_t b_byte_stride, + float* SKAINET_RESTRICT c, int32_t c_offset, int32_t c_stride, + int32_t m, int32_t n, int32_t k +) { + if (m <= 0 || n <= 0) return; + skainet_fp16_ctx ctx; + ctx.a = a + a_offset; + ctx.b = b + b_byte_offset; + ctx.c = c + c_offset; + ctx.a_stride = a_stride; + ctx.b_byte_stride = b_byte_stride; + ctx.c_stride = c_stride; + ctx.m = m; + ctx.n = n; + ctx.k = k < 0 ? 0 : k; + skainet_run_rows(skainet_fp16_columns, &ctx, n); +} diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/fp32_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/fp32_matmul.c index dbd6293b0..310de88cb 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/fp32_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/fp32_matmul.c @@ -1,5 +1,6 @@ #include "skainet_kernels.h" #include "skainet_simd.h" +#include "skainet_row_threads.h" #include #include @@ -14,11 +15,28 @@ * `aStride == k`, `bStride == n`, `cStride == n`. Sub-block scenarios * pass larger strides and the corresponding offsets. * - * Iteration order is i-p-j (outer product into rows of C). The inner - * loop is `c[j] += a_ip * b[j]` over a contiguous run of `n` floats - * for both b's row and c's row — auto-vectorizes cleanly under + * Portable and NEON bodies: iteration order is i-p-j (outer product into + * rows of C). The inner loop is `c[j] += a_ip * b[j]` over a contiguous run + * of `n` floats for both b's row and c's row — auto-vectorizes cleanly under * -O3 -ffast-math into vfmadd231ps / fmla. * + * SIMD128 body (the Emscripten sidecar): a 4×8 register-blocked micro-kernel. + * Eight f32x4 accumulators hold a 4-row × 8-column tile of C for a whole + * k-block, so per p the loop issues two B loads, four A broadcasts and eight + * multiply-adds instead of a load/multiply-add/store triple per four + * outputs. k is blocked so the B panel a tile streams (8 columns × K_BLOCK + * rows) stays in L1 while the tile walks down the rows of A. Every C element + * still accumulates its products in ascending p — the partial sum is carried + * in C between k-blocks — so the result is bit-identical to the portable + * body (SIMD128 has no fused multiply-add; the portable body is compiled + * without FMA contraction on that target too). + * + * Threading (#1195 pattern, skainet_row_threads.h): the output is split over + * the longer of its two sides — rows of C when m ≥ n, columns otherwise — + * into disjoint ranges; workers never share a C element, so the partition + * does not change any accumulation order. On Emscripten the pool is the + * pthread pool of the mt sidecar; the st sidecar and MSVC run on the caller. + * * Caller contract: * - C is FULLY OVERWRITTEN in the m×n block (zero-then-accumulate). * - k == 0 zeros the m×n block. @@ -27,49 +45,159 @@ * them. The C kernel still treats negatives as no-op (via the * `<=` loop bounds) defensively. */ -SKAINET_API void skainet_fp32_matmul( - const float* SKAINET_RESTRICT a, int32_t a_offset, int32_t a_stride, - const float* SKAINET_RESTRICT b, int32_t b_offset, int32_t b_stride, - float* SKAINET_RESTRICT c, int32_t c_offset, int32_t c_stride, - int32_t m, int32_t n, int32_t k + +typedef struct { + const float* a; /* a + a_offset */ + const float* b; /* b + b_offset */ + float* c; /* c + c_offset */ + int32_t a_stride, b_stride, c_stride; + int32_t m, n, k; + int split_rows; /* 1: worker ranges are rows of C; 0: columns */ +} skainet_fp32_gemm_ctx; + +#ifdef SKAINET_HAVE_WASM_SIMD128 + +#define SKAINET_FP32_K_BLOCK 256 + +/* C[i0..i0+4, j0..j0+8] over p in [p0, p1): eight accumulators, carried in C. */ +static inline void skainet_fp32_tile_4x8( + const skainet_fp32_gemm_ctx* c, int32_t i0, int32_t j0, int32_t p0, int32_t p1 ) { - if (m <= 0 || n <= 0) return; + const float* a0 = c->a + (size_t) i0 * c->a_stride; + const float* a1 = a0 + c->a_stride; + const float* a2 = a1 + c->a_stride; + const float* a3 = a2 + c->a_stride; + float* c0 = c->c + (size_t) i0 * c->c_stride + j0; + float* c1 = c0 + c->c_stride; + float* c2 = c1 + c->c_stride; + float* c3 = c2 + c->c_stride; + v128_t acc00 = wasm_v128_load(c0), acc01 = wasm_v128_load(c0 + 4); + v128_t acc10 = wasm_v128_load(c1), acc11 = wasm_v128_load(c1 + 4); + v128_t acc20 = wasm_v128_load(c2), acc21 = wasm_v128_load(c2 + 4); + v128_t acc30 = wasm_v128_load(c3), acc31 = wasm_v128_load(c3 + 4); + const float* b_row = c->b + (size_t) p0 * c->b_stride + j0; + for (int32_t p = p0; p < p1; ++p, b_row += c->b_stride) { + const v128_t b0 = wasm_v128_load(b_row); + const v128_t b1 = wasm_v128_load(b_row + 4); + const v128_t va0 = wasm_f32x4_splat(a0[p]); + const v128_t va1 = wasm_f32x4_splat(a1[p]); + const v128_t va2 = wasm_f32x4_splat(a2[p]); + const v128_t va3 = wasm_f32x4_splat(a3[p]); + acc00 = wasm_f32x4_add(acc00, wasm_f32x4_mul(va0, b0)); + acc01 = wasm_f32x4_add(acc01, wasm_f32x4_mul(va0, b1)); + acc10 = wasm_f32x4_add(acc10, wasm_f32x4_mul(va1, b0)); + acc11 = wasm_f32x4_add(acc11, wasm_f32x4_mul(va1, b1)); + acc20 = wasm_f32x4_add(acc20, wasm_f32x4_mul(va2, b0)); + acc21 = wasm_f32x4_add(acc21, wasm_f32x4_mul(va2, b1)); + acc30 = wasm_f32x4_add(acc30, wasm_f32x4_mul(va3, b0)); + acc31 = wasm_f32x4_add(acc31, wasm_f32x4_mul(va3, b1)); + } + wasm_v128_store(c0, acc00); wasm_v128_store(c0 + 4, acc01); + wasm_v128_store(c1, acc10); wasm_v128_store(c1 + 4, acc11); + wasm_v128_store(c2, acc20); wasm_v128_store(c2 + 4, acc21); + wasm_v128_store(c3, acc30); wasm_v128_store(c3 + 4, acc31); +} + +/* Edge: rows [i0, i1) × columns [j0, j1) over p in [p0, p1), i-p-j with 4-lane runs and a scalar tail. */ +static inline void skainet_fp32_edge( + const skainet_fp32_gemm_ctx* c, int32_t i0, int32_t i1, int32_t j0, int32_t j1, int32_t p0, int32_t p1 +) { + for (int32_t i = i0; i < i1; ++i) { + const float* a_row = c->a + (size_t) i * c->a_stride; + float* c_row = c->c + (size_t) i * c->c_stride; + const float* b_row = c->b + (size_t) p0 * c->b_stride; + for (int32_t p = p0; p < p1; ++p, b_row += c->b_stride) { + const float a_ip = a_row[p]; + const v128_t va = wasm_f32x4_splat(a_ip); + int32_t j = j0; + for (; j + 4 <= j1; j += 4) { + wasm_v128_store(c_row + j, wasm_f32x4_add(wasm_v128_load(c_row + j), + wasm_f32x4_mul(va, wasm_v128_load(b_row + j)))); + } + for (; j < j1; ++j) c_row[j] += a_ip * b_row[j]; + } + } +} - /* Zero the output block. Required by the SPI contract for k == 0 - * AND prerequisite for the i-p-j accumulator pattern below. */ - for (int32_t i = 0; i < m; ++i) { - float* SKAINET_RESTRICT c_row = c + c_offset + (size_t) i * c_stride; - for (int32_t j = 0; j < n; ++j) { - c_row[j] = 0.0f; +/* Rows [i0, i1) × columns [j0, j1) of C, k-blocked, tiles first and edges after. */ +static void skainet_fp32_block(const skainet_fp32_gemm_ctx* c, int32_t i0, int32_t i1, int32_t j0, int32_t j1) { + for (int32_t i = i0; i < i1; ++i) { + float* c_row = c->c + (size_t) i * c->c_stride; + for (int32_t j = j0; j < j1; ++j) c_row[j] = 0.0f; + } + if (c->k <= 0) return; + const int32_t i_tiles_end = i0 + ((i1 - i0) / 4) * 4; + const int32_t j_tiles_end = j0 + ((j1 - j0) / 8) * 8; + for (int32_t p0 = 0; p0 < c->k; p0 += SKAINET_FP32_K_BLOCK) { + const int32_t p1 = (c->k - p0) < SKAINET_FP32_K_BLOCK ? c->k : p0 + SKAINET_FP32_K_BLOCK; + for (int32_t j = j0; j < j_tiles_end; j += 8) { + for (int32_t i = i0; i < i_tiles_end; i += 4) skainet_fp32_tile_4x8(c, i, j, p0, p1); } + /* Remaining rows (< 4) across the tiled columns, then the remaining columns (< 8) for all rows. */ + skainet_fp32_edge(c, i_tiles_end, i1, j0, j_tiles_end, p0, p1); + skainet_fp32_edge(c, i0, i1, j_tiles_end, j1, p0, p1); } - if (k <= 0) return; +} + +#else /* portable + NEON: i-p-j outer product over the block */ - /* Outer-product accumulator: streams two contiguous rows on the - * inner loop (b's row and c's row), broadcasts a single A scalar. - * The compiler emits vfmadd231ps with a vbroadcastss for a_ip. */ - for (int32_t i = 0; i < m; ++i) { - const float* SKAINET_RESTRICT a_row = a + a_offset + (size_t) i * a_stride; - float* SKAINET_RESTRICT c_row = c + c_offset + (size_t) i * c_stride; - for (int32_t p = 0; p < k; ++p) { +static void skainet_fp32_block(const skainet_fp32_gemm_ctx* c, int32_t i0, int32_t i1, int32_t j0, int32_t j1) { + for (int32_t i = i0; i < i1; ++i) { + float* SKAINET_RESTRICT c_row = c->c + (size_t) i * c->c_stride; + for (int32_t j = j0; j < j1; ++j) c_row[j] = 0.0f; + } + if (c->k <= 0) return; + for (int32_t i = i0; i < i1; ++i) { + const float* SKAINET_RESTRICT a_row = c->a + (size_t) i * c->a_stride; + float* SKAINET_RESTRICT c_row = c->c + (size_t) i * c->c_stride; + for (int32_t p = 0; p < c->k; ++p) { const float a_ip = a_row[p]; - const float* SKAINET_RESTRICT b_row = b + b_offset + (size_t) p * b_stride; + const float* SKAINET_RESTRICT b_row = c->b + (size_t) p * c->b_stride; #ifdef SKAINET_HAVE_NEON const float32x4_t va = vdupq_n_f32(a_ip); - int32_t j = 0; - for (; j + 4 <= n; j += 4) { + int32_t j = j0; + for (; j + 4 <= j1; j += 4) { float32x4_t cv = vld1q_f32(c_row + j); cv = vfmaq_f32(cv, va, vld1q_f32(b_row + j)); vst1q_f32(c_row + j, cv); } - for (; j < n; ++j) { + for (; j < j1; ++j) { c_row[j] += a_ip * b_row[j]; } #else - for (int32_t j = 0; j < n; ++j) { + for (int32_t j = j0; j < j1; ++j) { c_row[j] += a_ip * b_row[j]; } #endif } } } + +#endif + +static void skainet_fp32_gemm_range(void* vctx, int32_t start, int32_t end) { + const skainet_fp32_gemm_ctx* c = (const skainet_fp32_gemm_ctx*) vctx; + if (c->split_rows) skainet_fp32_block(c, start, end, 0, c->n); + else skainet_fp32_block(c, 0, c->m, start, end); +} + +SKAINET_API void skainet_fp32_matmul( + const float* SKAINET_RESTRICT a, int32_t a_offset, int32_t a_stride, + const float* SKAINET_RESTRICT b, int32_t b_offset, int32_t b_stride, + float* SKAINET_RESTRICT c, int32_t c_offset, int32_t c_stride, + int32_t m, int32_t n, int32_t k +) { + if (m <= 0 || n <= 0) return; + skainet_fp32_gemm_ctx ctx; + ctx.a = a + a_offset; + ctx.b = b + b_offset; + ctx.c = c + c_offset; + ctx.a_stride = a_stride; + ctx.b_stride = b_stride; + ctx.c_stride = c_stride; + ctx.m = m; + ctx.n = n; + ctx.k = k < 0 ? 0 : k; + ctx.split_rows = m >= n; + skainet_run_rows(skainet_fp32_gemm_range, &ctx, ctx.split_rows ? m : n); +} diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/q4k_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/q4k_matmul.c index e5fc011f3..1bf71d03e 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/q4k_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/q4k_matmul.c @@ -156,6 +156,27 @@ static void skainet_q4k_block_dot_generic( const int8_t* q8_hi = q8_block + sb_hi * Q4K_SUB_BLOCK_SIZE; int32_t dot_lo = 0, sum_lo = 0, dot_hi = 0, sum_hi = 0; +#ifdef SKAINET_HAVE_WASM_SIMD128 + /* SIMD128 body (SKEEP-007 §T1): the dotprod structure on i16 pair dots — + * nibbles stay unsigned u8 codes, the int8 activation widens alongside. */ + v128_t acc_dot_lo = wasm_i32x4_splat(0), acc_dot_hi = wasm_i32x4_splat(0); + v128_t acc_sum_lo = wasm_i32x4_splat(0), acc_sum_hi = wasm_i32x4_splat(0); + for (int off = 0; off < Q4K_SUB_BLOCK_SIZE; off += 16) { + const v128_t packed = wasm_v128_load(qs_group + off); + const v128_t code_lo = wasm_v128_and(packed, wasm_i8x16_splat(0x0F)); + const v128_t code_hi = wasm_u8x16_shr(packed, 4); + const v128_t a_lo = wasm_v128_load(q8_lo + off); + const v128_t a_hi = wasm_v128_load(q8_hi + off); + acc_dot_lo = wasm_i32x4_add(acc_dot_lo, skainet_wasm_dot_u8x16_i8x16(code_lo, a_lo)); + acc_dot_hi = wasm_i32x4_add(acc_dot_hi, skainet_wasm_dot_u8x16_i8x16(code_hi, a_hi)); + acc_sum_lo = wasm_i32x4_add(acc_sum_lo, skainet_wasm_sum_i8x16(a_lo)); + acc_sum_hi = wasm_i32x4_add(acc_sum_hi, skainet_wasm_sum_i8x16(a_hi)); + } + dot_lo = skainet_wasm_hadd_i32(acc_dot_lo); + dot_hi = skainet_wasm_hadd_i32(acc_dot_hi); + sum_lo = skainet_wasm_hadd_i32(acc_sum_lo); + sum_hi = skainet_wasm_hadd_i32(acc_sum_hi); +#else for (int i = 0; i < Q4K_SUB_BLOCK_SIZE; ++i) { const uint8_t pb = qs_group[i]; const int code_lo = (int)(pb & 0x0F); @@ -167,6 +188,7 @@ static void skainet_q4k_block_dot_generic( dot_hi += a_hi * code_hi; sum_hi += a_hi; } +#endif *block_scale_dot += (int64_t) scale_idx[sb_lo] * dot_lo + (int64_t) scale_idx[sb_hi] * dot_hi; @@ -181,7 +203,8 @@ static void skainet_q4k_block_dot_generic( * d_in[b] * ( d * Σ_s scaleIdx[s]*intDot[s] - dMin * Σ_s minIdx[s]*intSum[s] ) * where intDot[s] = Σ q8[i]*code[i] and intSum[s] = Σ q8[i] over the sub-block. * On AArch64 with dotprod (asimddp) the inner dot uses vdotq_s32 (16 int8 MACs - * per instruction); otherwise a scalar integer fallback (auto-vectorized). + * per instruction); in the wasm sidecar i32x4.dot_i16x8_s over widened lanes; + * otherwise a scalar integer fallback (auto-vectorized). * Shared by the feed-order and row-major entries — identical math, so the two * orders (and any row partition, #1195) stay bit-identical per output row. */ diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/q5_0_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/q5_0_matmul.c index 856369ffd..702befe6a 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/q5_0_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/q5_0_matmul.c @@ -129,6 +129,30 @@ static inline float q5_0_block_term( accv = vfmaq_f32(accv, vld1q_f32(input_block + 24), hi_f[2]); accv = vfmaq_f32(accv, vld1q_f32(input_block + 28), hi_f[3]); code_dot = skainet_neon_hadd_f32(accv); +#elif defined(SKAINET_HAVE_WASM_SIMD128) + /* SIMD128 body (SKEEP-007 §T1): the NEON structure on 128-bit lanes — the + * fifth bits come from a byte swizzle + per-lane bit test (skainet_simd.h). */ + v128_t fifth_lo, fifth_hi; + skainet_wasm_q5_fifth_bits((uint32_t) qh[0] | ((uint32_t) qh[1] << 8) | + ((uint32_t) qh[2] << 16) | ((uint32_t) qh[3] << 24), + &fifth_lo, &fifth_hi); + const v128_t packed = wasm_v128_load(qs); + const v128_t code_lo = wasm_v128_or(wasm_v128_and(packed, wasm_i8x16_splat(0x0F)), fifth_lo); /* elems 0..15 */ + const v128_t code_hi = wasm_v128_or(wasm_u8x16_shr(packed, 4), fifth_hi); /* elems 16..31 */ + v128_t lo_f[4]; + v128_t hi_f[4]; + skainet_wasm_u8x16_to_f32x4x4(code_lo, lo_f); + skainet_wasm_u8x16_to_f32x4x4(code_hi, hi_f); + v128_t accv = wasm_f32x4_splat(0.0f); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 0), lo_f[0])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 4), lo_f[1])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 8), lo_f[2])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 12), lo_f[3])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 16), hi_f[0])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 20), hi_f[1])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 24), hi_f[2])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 28), hi_f[3])); + code_dot = skainet_wasm_hadd_f32(accv); #else uint32_t qh32 = (uint32_t) qh[0] | ((uint32_t) qh[1] << 8) | ((uint32_t) qh[2] << 16) | ((uint32_t) qh[3] << 24); diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/q5_1_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/q5_1_matmul.c index 6e6debaec..847e68afe 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/q5_1_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/q5_1_matmul.c @@ -129,6 +129,30 @@ static inline float q5_1_block_term( accv = vfmaq_f32(accv, vld1q_f32(input_block + 24), hi_f[2]); accv = vfmaq_f32(accv, vld1q_f32(input_block + 28), hi_f[3]); code_dot = skainet_neon_hadd_f32(accv); +#elif defined(SKAINET_HAVE_WASM_SIMD128) + /* SIMD128 body (SKEEP-007 §T1): the NEON structure on 128-bit lanes — the + * fifth bits come from a byte swizzle + per-lane bit test (skainet_simd.h). */ + v128_t fifth_lo, fifth_hi; + skainet_wasm_q5_fifth_bits((uint32_t) qh[0] | ((uint32_t) qh[1] << 8) | + ((uint32_t) qh[2] << 16) | ((uint32_t) qh[3] << 24), + &fifth_lo, &fifth_hi); + const v128_t packed = wasm_v128_load(qs); + const v128_t code_lo = wasm_v128_or(wasm_v128_and(packed, wasm_i8x16_splat(0x0F)), fifth_lo); /* elems 0..15 */ + const v128_t code_hi = wasm_v128_or(wasm_u8x16_shr(packed, 4), fifth_hi); /* elems 16..31 */ + v128_t lo_f[4]; + v128_t hi_f[4]; + skainet_wasm_u8x16_to_f32x4x4(code_lo, lo_f); + skainet_wasm_u8x16_to_f32x4x4(code_hi, hi_f); + v128_t accv = wasm_f32x4_splat(0.0f); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 0), lo_f[0])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 4), lo_f[1])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 8), lo_f[2])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 12), lo_f[3])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 16), hi_f[0])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 20), hi_f[1])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 24), hi_f[2])); + accv = wasm_f32x4_add(accv, wasm_f32x4_mul(wasm_v128_load(input_block + 28), hi_f[3])); + code_dot = skainet_wasm_hadd_f32(accv); #else uint32_t qh32 = (uint32_t) qh[0] | ((uint32_t) qh[1] << 8) | ((uint32_t) qh[2] << 16) | ((uint32_t) qh[3] << 24); diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/q5k_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/q5k_matmul.c index a5909be39..25f1a7e60 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/q5k_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/q5k_matmul.c @@ -81,9 +81,9 @@ static inline void skainet_q5k_decode_scales( * and combine once via * acc += d * scaleIdx[s] * codeSum[s] - dMin * minIdx[s] * inputSum[s] * - * Scalar single-threaded; the tight inner loop is straight-line FP - * arithmetic so -O3 auto-vectorizes on AVX2/NEON. A hand-written NEON - * path is layered on behind __ARM_NEON in a later PR. + * Explicit NEON and wasm SIMD128 bodies share the lane structure (unsigned + * 5-bit codes widened to f32 lanes, multiply-add against the activation); + * the portable loop is straight-line FP arithmetic that -O3 auto-vectorizes. */ /* * One block's contribution to out[o] — the loop body of the original kernel, @@ -159,6 +159,35 @@ static inline float q5k_block_term( input_sum_lo = skainet_neon_hadd_f32(iacc_lo); code_sum_hi = skainet_neon_hadd_f32(cacc_hi); input_sum_hi = skainet_neon_hadd_f32(iacc_hi); +#elif defined(SKAINET_HAVE_WASM_SIMD128) + /* SIMD128 body (SKEEP-007 §T1): the NEON structure on 128-bit lanes; the + * fifth-bit shift count is a runtime scalar, which u8x16.shr_u takes. */ + v128_t cacc_lo = wasm_f32x4_splat(0.0f), iacc_lo = wasm_f32x4_splat(0.0f); + v128_t cacc_hi = wasm_f32x4_splat(0.0f), iacc_hi = wasm_f32x4_splat(0.0f); + for (int off = 0; off < Q5K_SUB_BLOCK_SIZE; off += 16) { + const v128_t packed = wasm_v128_load(qs_group + off); + const v128_t qhv = wasm_v128_load(qh + off); + const v128_t one = wasm_i8x16_splat(0x01); + const v128_t lo_nib = wasm_v128_and(packed, wasm_i8x16_splat(0x0F)); + const v128_t hi_nib = wasm_u8x16_shr(packed, 4); + const v128_t fifth_lo = wasm_i8x16_shl(wasm_v128_and(wasm_u8x16_shr(qhv, bit_lo), one), 4); + const v128_t fifth_hi = wasm_i8x16_shl(wasm_v128_and(wasm_u8x16_shr(qhv, bit_hi), one), 4); + v128_t cl[4], ch[4]; + skainet_wasm_u8x16_to_f32x4x4(wasm_v128_or(lo_nib, fifth_lo), cl); + skainet_wasm_u8x16_to_f32x4x4(wasm_v128_or(hi_nib, fifth_hi), ch); + for (int q = 0; q < 4; ++q) { + const v128_t v_lo = wasm_v128_load(in_lo + off + q * 4); + const v128_t v_hi = wasm_v128_load(in_hi + off + q * 4); + cacc_lo = wasm_f32x4_add(cacc_lo, wasm_f32x4_mul(v_lo, cl[q])); + iacc_lo = wasm_f32x4_add(iacc_lo, v_lo); + cacc_hi = wasm_f32x4_add(cacc_hi, wasm_f32x4_mul(v_hi, ch[q])); + iacc_hi = wasm_f32x4_add(iacc_hi, v_hi); + } + } + code_sum_lo = skainet_wasm_hadd_f32(cacc_lo); + input_sum_lo = skainet_wasm_hadd_f32(iacc_lo); + code_sum_hi = skainet_wasm_hadd_f32(cacc_hi); + input_sum_hi = skainet_wasm_hadd_f32(iacc_hi); #else /* 32 iterations — auto-vectorizes cleanly under -O3. */ for (int i = 0; i < Q5K_SUB_BLOCK_SIZE; ++i) { diff --git a/skainet-backends/skainet-backend-native-cpu/native/src/q6k_matmul.c b/skainet-backends/skainet-backend-native-cpu/native/src/q6k_matmul.c index ea7d78742..fd2647e5e 100644 --- a/skainet-backends/skainet-backend-native-cpu/native/src/q6k_matmul.c +++ b/skainet-backends/skainet-backend-native-cpu/native/src/q6k_matmul.c @@ -91,6 +91,24 @@ static inline void skainet_q6k_unpack_codes(const uint8_t* SKAINET_RESTRICT bloc int8_t* out = codes + half * 128; for (int is = 0; is < 2; ++is) { const int l_start = is * 16; +#ifdef SKAINET_HAVE_WASM_SIMD128 + /* The 16-element scale group is exactly one lane vector per sub-code. */ + const v128_t nib = wasm_i8x16_splat(0x0F); + const v128_t two = wasm_i8x16_splat(0x03); + const v128_t bias = wasm_i8x16_splat(32); + const v128_t q_l0 = wasm_v128_load(ql + l_start); + const v128_t q_l32 = wasm_v128_load(ql + l_start + 32); + const v128_t q_h = wasm_v128_load(qh + l_start); + const v128_t h0 = wasm_i8x16_shl(wasm_v128_and(q_h, two), 4); + const v128_t h1 = wasm_i8x16_shl(wasm_v128_and(wasm_u8x16_shr(q_h, 2), two), 4); + const v128_t h2 = wasm_i8x16_shl(wasm_v128_and(wasm_u8x16_shr(q_h, 4), two), 4); + const v128_t h3 = wasm_i8x16_shl(wasm_u8x16_shr(q_h, 6), 4); + wasm_v128_store(out + l_start, wasm_i8x16_sub(wasm_v128_or(wasm_v128_and(q_l0, nib), h0), bias)); + wasm_v128_store(out + l_start + 32, wasm_i8x16_sub(wasm_v128_or(wasm_v128_and(q_l32, nib), h1), bias)); + wasm_v128_store(out + l_start + 64, wasm_i8x16_sub(wasm_v128_or(wasm_u8x16_shr(q_l0, 4), h2), bias)); + wasm_v128_store(out + l_start + 96, wasm_i8x16_sub(wasm_v128_or(wasm_u8x16_shr(q_l32, 4), h3), bias)); + continue; +#endif for (int l = l_start; l < l_start + 16; ++l) { const int q_l0 = ql[l]; const int q_l32 = ql[l + 32]; @@ -109,7 +127,8 @@ static inline void skainet_q6k_unpack_codes(const uint8_t* SKAINET_RESTRICT bloc * over the 16 scale-groups (each a 16-element contiguous run in natural order). * Run `r` for (half,k,is) starts at half*128 + 32*k + is*16 and uses signed * scale sc[half*8 + is + 2*k]. On AArch64 with dotprod each 16-element dot is a - * single vdotq_s32; otherwise a scalar fallback (auto-vectorizes under -O3). + * single vdotq_s32; in the wasm sidecar two i32x4.dot_i16x8_s over widened + * lanes; otherwise a scalar fallback (auto-vectorizes under -O3). */ #if defined(SKAINET_HAVE_DOTPROD) || defined(SKAINET_DOTPROD_DISPATCH) SKAINET_DOTPROD_TARGET @@ -142,8 +161,13 @@ static int64_t skainet_q6k_weighted_dot_generic(const int8_t* SKAINET_RESTRICT q for (int is = 0; is < 2; ++is) { const int start = half * 128 + 32 * k + is * 16; const int gs = half * 8 + is + 2 * k; +#ifdef SKAINET_HAVE_WASM_SIMD128 + const int32_t dot = skainet_wasm_hadd_i32( + skainet_wasm_dot_i8x16(wasm_v128_load(codes + start), wasm_v128_load(q8 + start))); +#else int32_t dot = 0; for (int j = 0; j < 16; ++j) dot += (int) q8[start + j] * (int) codes[start + j]; +#endif sum += (int64_t) sc[gs] * dot; } } diff --git a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/SidecarArtifacts.kt b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/SidecarArtifacts.kt index 9ebb691e4..b33356e50 100644 --- a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/SidecarArtifacts.kt +++ b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/SidecarArtifacts.kt @@ -1,13 +1,13 @@ // GENERATED by native/build-wasm.sh (emsdk 4.0.14) -- do not edit. // SKEEP-007 Tier 1: the SIMD128 kernel sidecar, embedded so every consumer of this module carries it. -// sha256 st: 5f73fc0102e7479620d159ff1711c05533a49590c17c9cdf2f0cffa08190591b -// sha256 mt: af98e98c4b39c043afbff4de34ea0fc0b10039d1c8631f189f931bf484fc97a2 +// sha256 st: c1a6213df16738714532551430ae508eb29154459336c5069bf27be3205ba3f3 +// sha256 mt: 590e0bfe8a35c5fa259305688d3c964c5bf3013fab611b5557dcce65d3b8b097 package sk.ainet.exec.wasm internal object SidecarArtifacts { const val EMSDK: String = "4.0.14" const val ST_MJS: String = "YXN5bmMgZnVuY3Rpb24gY3JlYXRlU2thaW5ldEtlcm5lbHMobW9kdWxlQXJnPXt9KXt2YXIgbW9kdWxlUnRuO3ZhciBNb2R1bGU9bW9kdWxlQXJnO3ZhciBFTlZJUk9OTUVOVF9JU19XRUI9dHlwZW9mIHdpbmRvdz09Im9iamVjdCI7dmFyIEVOVklST05NRU5UX0lTX1dPUktFUj10eXBlb2YgV29ya2VyR2xvYmFsU2NvcGUhPSJ1bmRlZmluZWQiO3ZhciBFTlZJUk9OTUVOVF9JU19OT0RFPXR5cGVvZiBwcm9jZXNzPT0ib2JqZWN0IiYmcHJvY2Vzcy52ZXJzaW9ucz8ubm9kZSYmcHJvY2Vzcy50eXBlIT0icmVuZGVyZXIiO2lmKEVOVklST05NRU5UX0lTX05PREUpe2NvbnN0e2NyZWF0ZVJlcXVpcmV9PWF3YWl0IGltcG9ydCgibW9kdWxlIik7dmFyIHJlcXVpcmU9Y3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwuc3RhcnRzV2l0aCgiZmlsZToiKT9pbXBvcnQubWV0YS51cmw6cHJvY2Vzcy5jd2QoKSsiLyIpfXZhciBhcmd1bWVudHNfPVtdO3ZhciB0aGlzUHJvZ3JhbT0iLi90aGlzLnByb2dyYW0iO3ZhciBxdWl0Xz0oc3RhdHVzLHRvVGhyb3cpPT57dGhyb3cgdG9UaHJvd307dmFyIF9zY3JpcHROYW1lPWltcG9ydC5tZXRhLnVybDt2YXIgc2NyaXB0RGlyZWN0b3J5PSIiO2Z1bmN0aW9uIGxvY2F0ZUZpbGUocGF0aCl7aWYoTW9kdWxlWyJsb2NhdGVGaWxlIl0pe3JldHVybiBNb2R1bGVbImxvY2F0ZUZpbGUiXShwYXRoLHNjcmlwdERpcmVjdG9yeSl9cmV0dXJuIHNjcmlwdERpcmVjdG9yeStwYXRofXZhciByZWFkQXN5bmMscmVhZEJpbmFyeTtpZihFTlZJUk9OTUVOVF9JU19OT0RFKXt2YXIgZnM9cmVxdWlyZSgiZnMiKTtpZihfc2NyaXB0TmFtZS5zdGFydHNXaXRoKCJmaWxlOiIpKXtzY3JpcHREaXJlY3Rvcnk9cmVxdWlyZSgicGF0aCIpLmRpcm5hbWUocmVxdWlyZSgidXJsIikuZmlsZVVSTFRvUGF0aChfc2NyaXB0TmFtZSkpKyIvIn1yZWFkQmluYXJ5PWZpbGVuYW1lPT57ZmlsZW5hbWU9aXNGaWxlVVJJKGZpbGVuYW1lKT9uZXcgVVJMKGZpbGVuYW1lKTpmaWxlbmFtZTt2YXIgcmV0PWZzLnJlYWRGaWxlU3luYyhmaWxlbmFtZSk7cmV0dXJuIHJldH07cmVhZEFzeW5jPWFzeW5jKGZpbGVuYW1lLGJpbmFyeT10cnVlKT0+e2ZpbGVuYW1lPWlzRmlsZVVSSShmaWxlbmFtZSk/bmV3IFVSTChmaWxlbmFtZSk6ZmlsZW5hbWU7dmFyIHJldD1mcy5yZWFkRmlsZVN5bmMoZmlsZW5hbWUsYmluYXJ5P3VuZGVmaW5lZDoidXRmOCIpO3JldHVybiByZXR9O2lmKHByb2Nlc3MuYXJndi5sZW5ndGg+MSl7dGhpc1Byb2dyYW09cHJvY2Vzcy5hcmd2WzFdLnJlcGxhY2UoL1xcL2csIi8iKX1hcmd1bWVudHNfPXByb2Nlc3MuYXJndi5zbGljZSgyKTtxdWl0Xz0oc3RhdHVzLHRvVGhyb3cpPT57cHJvY2Vzcy5leGl0Q29kZT1zdGF0dXM7dGhyb3cgdG9UaHJvd319ZWxzZSBpZihFTlZJUk9OTUVOVF9JU19XRUJ8fEVOVklST05NRU5UX0lTX1dPUktFUil7dHJ5e3NjcmlwdERpcmVjdG9yeT1uZXcgVVJMKCIuIixfc2NyaXB0TmFtZSkuaHJlZn1jYXRjaHt9e2lmKEVOVklST05NRU5UX0lTX1dPUktFUil7cmVhZEJpbmFyeT11cmw9Pnt2YXIgeGhyPW5ldyBYTUxIdHRwUmVxdWVzdDt4aHIub3BlbigiR0VUIix1cmwsZmFsc2UpO3hoci5yZXNwb25zZVR5cGU9ImFycmF5YnVmZmVyIjt4aHIuc2VuZChudWxsKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeGhyLnJlc3BvbnNlKX19cmVhZEFzeW5jPWFzeW5jIHVybD0+e3ZhciByZXNwb25zZT1hd2FpdCBmZXRjaCh1cmwse2NyZWRlbnRpYWxzOiJzYW1lLW9yaWdpbiJ9KTtpZihyZXNwb25zZS5vayl7cmV0dXJuIHJlc3BvbnNlLmFycmF5QnVmZmVyKCl9dGhyb3cgbmV3IEVycm9yKHJlc3BvbnNlLnN0YXR1cysiIDogIityZXNwb25zZS51cmwpfX19ZWxzZXt9dmFyIG91dD1jb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO3ZhciBlcnI9Y29uc29sZS5lcnJvci5iaW5kKGNvbnNvbGUpO3ZhciB3YXNtQmluYXJ5O3ZhciBBQk9SVD1mYWxzZTt2YXIgaXNGaWxlVVJJPWZpbGVuYW1lPT5maWxlbmFtZS5zdGFydHNXaXRoKCJmaWxlOi8vIik7dmFyIHJlYWR5UHJvbWlzZVJlc29sdmUscmVhZHlQcm9taXNlUmVqZWN0O3ZhciB3YXNtTWVtb3J5O3ZhciBIRUFQOCxIRUFQVTgsSEVBUDE2LEhFQVBVMTYsSEVBUDMyLEhFQVBVMzIsSEVBUEYzMixIRUFQRjY0O3ZhciBIRUFQNjQsSEVBUFU2NDt2YXIgcnVudGltZUluaXRpYWxpemVkPWZhbHNlO2Z1bmN0aW9uIHVwZGF0ZU1lbW9yeVZpZXdzKCl7dmFyIGI9d2FzbU1lbW9yeS5idWZmZXI7SEVBUDg9bmV3IEludDhBcnJheShiKTtIRUFQMTY9bmV3IEludDE2QXJyYXkoYik7SEVBUFU4PW5ldyBVaW50OEFycmF5KGIpO0hFQVBVMTY9bmV3IFVpbnQxNkFycmF5KGIpO0hFQVAzMj1uZXcgSW50MzJBcnJheShiKTtIRUFQVTMyPW5ldyBVaW50MzJBcnJheShiKTtIRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYik7SEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGIpO0hFQVA2ND1uZXcgQmlnSW50NjRBcnJheShiKTtIRUFQVTY0PW5ldyBCaWdVaW50NjRBcnJheShiKX1mdW5jdGlvbiBwcmVSdW4oKXtpZihNb2R1bGVbInByZVJ1biJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInByZVJ1biJdPVtNb2R1bGVbInByZVJ1biJdXTt3aGlsZShNb2R1bGVbInByZVJ1biJdLmxlbmd0aCl7YWRkT25QcmVSdW4oTW9kdWxlWyJwcmVSdW4iXS5zaGlmdCgpKX19Y2FsbFJ1bnRpbWVDYWxsYmFja3Mob25QcmVSdW5zKX1mdW5jdGlvbiBpbml0UnVudGltZSgpe3J1bnRpbWVJbml0aWFsaXplZD10cnVlO3dhc21FeHBvcnRzWyJjIl0oKX1mdW5jdGlvbiBwb3N0UnVuKCl7aWYoTW9kdWxlWyJwb3N0UnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInBvc3RSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInBvc3RSdW4iXT1bTW9kdWxlWyJwb3N0UnVuIl1dO3doaWxlKE1vZHVsZVsicG9zdFJ1biJdLmxlbmd0aCl7YWRkT25Qb3N0UnVuKE1vZHVsZVsicG9zdFJ1biJdLnNoaWZ0KCkpfX1jYWxsUnVudGltZUNhbGxiYWNrcyhvblBvc3RSdW5zKX1mdW5jdGlvbiBhYm9ydCh3aGF0KXtNb2R1bGVbIm9uQWJvcnQiXT8uKHdoYXQpO3doYXQ9IkFib3J0ZWQoIit3aGF0KyIpIjtlcnIod2hhdCk7QUJPUlQ9dHJ1ZTt3aGF0Kz0iLiBCdWlsZCB3aXRoIC1zQVNTRVJUSU9OUyBmb3IgbW9yZSBpbmZvLiI7dmFyIGU9bmV3IFdlYkFzc2VtYmx5LlJ1bnRpbWVFcnJvcih3aGF0KTtyZWFkeVByb21pc2VSZWplY3Q/LihlKTt0aHJvdyBlfXZhciB3YXNtQmluYXJ5RmlsZTtmdW5jdGlvbiBmaW5kV2FzbUJpbmFyeSgpe2lmKE1vZHVsZVsibG9jYXRlRmlsZSJdKXtyZXR1cm4gbG9jYXRlRmlsZSgic2thaW5ldF9rZXJuZWxzX3N0Lndhc20iKX10cnl7cmV0dXJuIG5ldyBVUkwoInNrYWluZXRfa2VybmVsc19zdC53YXNtIixpbXBvcnQubWV0YS51cmwpLmhyZWZ9Y2F0Y2goZSl7cmV0dXJuICJza2FpbmV0X2tlcm5lbHNfc3Qud2FzbSJ9fWZ1bmN0aW9uIGdldEJpbmFyeVN5bmMoZmlsZSl7aWYoZmlsZT09d2FzbUJpbmFyeUZpbGUmJndhc21CaW5hcnkpe3JldHVybiBuZXcgVWludDhBcnJheSh3YXNtQmluYXJ5KX1pZihyZWFkQmluYXJ5KXtyZXR1cm4gcmVhZEJpbmFyeShmaWxlKX10aHJvdyJib3RoIGFzeW5jIGFuZCBzeW5jIGZldGNoaW5nIG9mIHRoZSB3YXNtIGZhaWxlZCJ9YXN5bmMgZnVuY3Rpb24gZ2V0V2FzbUJpbmFyeShiaW5hcnlGaWxlKXtpZighd2FzbUJpbmFyeSl7dHJ5e3ZhciByZXNwb25zZT1hd2FpdCByZWFkQXN5bmMoYmluYXJ5RmlsZSk7cmV0dXJuIG5ldyBVaW50OEFycmF5KHJlc3BvbnNlKX1jYXRjaHt9fXJldHVybiBnZXRCaW5hcnlTeW5jKGJpbmFyeUZpbGUpfWFzeW5jIGZ1bmN0aW9uIGluc3RhbnRpYXRlQXJyYXlCdWZmZXIoYmluYXJ5RmlsZSxpbXBvcnRzKXt0cnl7dmFyIGJpbmFyeT1hd2FpdCBnZXRXYXNtQmluYXJ5KGJpbmFyeUZpbGUpO3ZhciBpbnN0YW5jZT1hd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShiaW5hcnksaW1wb3J0cyk7cmV0dXJuIGluc3RhbmNlfWNhdGNoKHJlYXNvbil7ZXJyKGBmYWlsZWQgdG8gYXN5bmNocm9ub3VzbHkgcHJlcGFyZSB3YXNtOiAke3JlYXNvbn1gKTthYm9ydChyZWFzb24pfX1hc3luYyBmdW5jdGlvbiBpbnN0YW50aWF0ZUFzeW5jKGJpbmFyeSxiaW5hcnlGaWxlLGltcG9ydHMpe2lmKCFiaW5hcnkmJiFFTlZJUk9OTUVOVF9JU19OT0RFKXt0cnl7dmFyIHJlc3BvbnNlPWZldGNoKGJpbmFyeUZpbGUse2NyZWRlbnRpYWxzOiJzYW1lLW9yaWdpbiJ9KTt2YXIgaW5zdGFudGlhdGlvblJlc3VsdD1hd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZyhyZXNwb25zZSxpbXBvcnRzKTtyZXR1cm4gaW5zdGFudGlhdGlvblJlc3VsdH1jYXRjaChyZWFzb24pe2Vycihgd2FzbSBzdHJlYW1pbmcgY29tcGlsZSBmYWlsZWQ6ICR7cmVhc29ufWApO2VycigiZmFsbGluZyBiYWNrIHRvIEFycmF5QnVmZmVyIGluc3RhbnRpYXRpb24iKX19cmV0dXJuIGluc3RhbnRpYXRlQXJyYXlCdWZmZXIoYmluYXJ5RmlsZSxpbXBvcnRzKX1mdW5jdGlvbiBnZXRXYXNtSW1wb3J0cygpe3JldHVybnthOndhc21JbXBvcnRzfX1hc3luYyBmdW5jdGlvbiBjcmVhdGVXYXNtKCl7ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbmNlKGluc3RhbmNlLG1vZHVsZSl7d2FzbUV4cG9ydHM9aW5zdGFuY2UuZXhwb3J0czt3YXNtRXhwb3J0cz1hcHBseVNpZ25hdHVyZUNvbnZlcnNpb25zKHdhc21FeHBvcnRzKTt3YXNtTWVtb3J5PXdhc21FeHBvcnRzWyJiIl07TW9kdWxlWyJ3YXNtTWVtb3J5Il09d2FzbU1lbW9yeTt1cGRhdGVNZW1vcnlWaWV3cygpO2Fzc2lnbldhc21FeHBvcnRzKHdhc21FeHBvcnRzKTtyZXR1cm4gd2FzbUV4cG9ydHN9ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KXtyZXR1cm4gcmVjZWl2ZUluc3RhbmNlKHJlc3VsdFsiaW5zdGFuY2UiXSl9dmFyIGluZm89Z2V0V2FzbUltcG9ydHMoKTtpZihNb2R1bGVbImluc3RhbnRpYXRlV2FzbSJdKXtyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUscmVqZWN0KT0+e01vZHVsZVsiaW5zdGFudGlhdGVXYXNtIl0oaW5mbywobW9kLGluc3QpPT57cmVzb2x2ZShyZWNlaXZlSW5zdGFuY2UobW9kLGluc3QpKX0pfSl9d2FzbUJpbmFyeUZpbGU/Pz1maW5kV2FzbUJpbmFyeSgpO3ZhciByZXN1bHQ9YXdhaXQgaW5zdGFudGlhdGVBc3luYyh3YXNtQmluYXJ5LHdhc21CaW5hcnlGaWxlLGluZm8pO3ZhciBleHBvcnRzPXJlY2VpdmVJbnN0YW50aWF0aW9uUmVzdWx0KHJlc3VsdCk7cmV0dXJuIGV4cG9ydHN9Y2xhc3MgRXhpdFN0YXR1c3tuYW1lPSJFeGl0U3RhdHVzIjtjb25zdHJ1Y3RvcihzdGF0dXMpe3RoaXMubWVzc2FnZT1gUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdCgke3N0YXR1c30pYDt0aGlzLnN0YXR1cz1zdGF0dXN9fXZhciBjYWxsUnVudGltZUNhbGxiYWNrcz1jYWxsYmFja3M9Pnt3aGlsZShjYWxsYmFja3MubGVuZ3RoPjApe2NhbGxiYWNrcy5zaGlmdCgpKE1vZHVsZSl9fTt2YXIgb25Qb3N0UnVucz1bXTt2YXIgYWRkT25Qb3N0UnVuPWNiPT5vblBvc3RSdW5zLnB1c2goY2IpO3ZhciBvblByZVJ1bnM9W107dmFyIGFkZE9uUHJlUnVuPWNiPT5vblByZVJ1bnMucHVzaChjYik7dmFyIG5vRXhpdFJ1bnRpbWU9dHJ1ZTt2YXIgZ2V0SGVhcE1heD0oKT0+NDI5NDkwMTc2MDt2YXIgYWxpZ25NZW1vcnk9KHNpemUsYWxpZ25tZW50KT0+TWF0aC5jZWlsKHNpemUvYWxpZ25tZW50KSphbGlnbm1lbnQ7dmFyIGdyb3dNZW1vcnk9c2l6ZT0+e3ZhciBvbGRIZWFwU2l6ZT13YXNtTWVtb3J5LmJ1ZmZlci5ieXRlTGVuZ3RoO3ZhciBwYWdlcz0oc2l6ZS1vbGRIZWFwU2l6ZSs2NTUzNSkvNjU1MzZ8MDt0cnl7d2FzbU1lbW9yeS5ncm93KHBhZ2VzKTt1cGRhdGVNZW1vcnlWaWV3cygpO3JldHVybiAxfWNhdGNoKGUpe319O2Z1bmN0aW9uIF9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwKHJlcXVlc3RlZFNpemUpe3JlcXVlc3RlZFNpemU+Pj49MDt2YXIgb2xkU2l6ZT1IRUFQVTgubGVuZ3RoO3ZhciBtYXhIZWFwU2l6ZT1nZXRIZWFwTWF4KCk7aWYocmVxdWVzdGVkU2l6ZT5tYXhIZWFwU2l6ZSl7cmV0dXJuIGZhbHNlfWZvcih2YXIgY3V0RG93bj0xO2N1dERvd248PTQ7Y3V0RG93bio9Mil7dmFyIG92ZXJHcm93bkhlYXBTaXplPW9sZFNpemUqKDErLjIvY3V0RG93bik7b3Zlckdyb3duSGVhcFNpemU9TWF0aC5taW4ob3Zlckdyb3duSGVhcFNpemUscmVxdWVzdGVkU2l6ZSsxMDA2NjMyOTYpO3ZhciBuZXdTaXplPU1hdGgubWluKG1heEhlYXBTaXplLGFsaWduTWVtb3J5KE1hdGgubWF4KHJlcXVlc3RlZFNpemUsb3Zlckdyb3duSGVhcFNpemUpLDY1NTM2KSk7dmFyIHJlcGxhY2VtZW50PWdyb3dNZW1vcnkobmV3U2l6ZSk7aWYocmVwbGFjZW1lbnQpe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9e2lmKE1vZHVsZVsibm9FeGl0UnVudGltZSJdKW5vRXhpdFJ1bnRpbWU9TW9kdWxlWyJub0V4aXRSdW50aW1lIl07aWYoTW9kdWxlWyJwcmludCJdKW91dD1Nb2R1bGVbInByaW50Il07aWYoTW9kdWxlWyJwcmludEVyciJdKWVycj1Nb2R1bGVbInByaW50RXJyIl07aWYoTW9kdWxlWyJ3YXNtQmluYXJ5Il0pd2FzbUJpbmFyeT1Nb2R1bGVbIndhc21CaW5hcnkiXTtpZihNb2R1bGVbImFyZ3VtZW50cyJdKWFyZ3VtZW50c189TW9kdWxlWyJhcmd1bWVudHMiXTtpZihNb2R1bGVbInRoaXNQcm9ncmFtIl0pdGhpc1Byb2dyYW09TW9kdWxlWyJ0aGlzUHJvZ3JhbSJdO2lmKE1vZHVsZVsicHJlSW5pdCJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVJbml0Il09PSJmdW5jdGlvbiIpTW9kdWxlWyJwcmVJbml0Il09W01vZHVsZVsicHJlSW5pdCJdXTt3aGlsZShNb2R1bGVbInByZUluaXQiXS5sZW5ndGg+MCl7TW9kdWxlWyJwcmVJbml0Il0uc2hpZnQoKSgpfX19TW9kdWxlWyJ3YXNtTWVtb3J5Il09d2FzbU1lbW9yeTt2YXIgX3NrYWluZXRfZnAzMl9tYXRtdWwsX3NrYWluZXRfZnAzMl9tYXRtdWxfd3QsX3NrYWluZXRfYmYxNl9tYXRtdWwsX3NrYWluZXRfZnAxNl9tYXRtdWwsX3NrYWluZXRfcTRfMF9tYXRtdWwsX3NrYWluZXRfcTRfMF9tYXRtdWxfcm0sX3NrYWluZXRfcTVfMF9tYXRtdWwsX21hbGxvYyxfZnJlZSxfc2thaW5ldF9xNV8wX21hdG11bF9ybSxfc2thaW5ldF9xNV8xX21hdG11bCxfc2thaW5ldF9xNV8xX21hdG11bF9ybSxfc2thaW5ldF9xOF8wX21hdG11bCxfc2thaW5ldF9xOF8wX21hdG11bF9ybSxfc2thaW5ldF9xNGtfbWF0bXVsLF9za2FpbmV0X3E0a19tYXRtdWxfcm0sX3NrYWluZXRfcTVrX21hdG11bCxfc2thaW5ldF9xNWtfbWF0bXVsX3JtLF9za2FpbmV0X3E2a19tYXRtdWwsX3NrYWluZXRfcTZrX21hdG11bF9ybTtmdW5jdGlvbiBhc3NpZ25XYXNtRXhwb3J0cyh3YXNtRXhwb3J0cyl7TW9kdWxlWyJfc2thaW5ldF9mcDMyX21hdG11bCJdPV9za2FpbmV0X2ZwMzJfbWF0bXVsPXdhc21FeHBvcnRzWyJkIl07TW9kdWxlWyJfc2thaW5ldF9mcDMyX21hdG11bF93dCJdPV9za2FpbmV0X2ZwMzJfbWF0bXVsX3d0PXdhc21FeHBvcnRzWyJlIl07TW9kdWxlWyJfc2thaW5ldF9iZjE2X21hdG11bCJdPV9za2FpbmV0X2JmMTZfbWF0bXVsPXdhc21FeHBvcnRzWyJmIl07TW9kdWxlWyJfc2thaW5ldF9mcDE2X21hdG11bCJdPV9za2FpbmV0X2ZwMTZfbWF0bXVsPXdhc21FeHBvcnRzWyJnIl07TW9kdWxlWyJfc2thaW5ldF9xNF8wX21hdG11bCJdPV9za2FpbmV0X3E0XzBfbWF0bXVsPXdhc21FeHBvcnRzWyJoIl07TW9kdWxlWyJfc2thaW5ldF9xNF8wX21hdG11bF9ybSJdPV9za2FpbmV0X3E0XzBfbWF0bXVsX3JtPXdhc21FeHBvcnRzWyJpIl07TW9kdWxlWyJfc2thaW5ldF9xNV8wX21hdG11bCJdPV9za2FpbmV0X3E1XzBfbWF0bXVsPXdhc21FeHBvcnRzWyJqIl07TW9kdWxlWyJfbWFsbG9jIl09X21hbGxvYz13YXNtRXhwb3J0c1siayJdO01vZHVsZVsiX2ZyZWUiXT1fZnJlZT13YXNtRXhwb3J0c1sibCJdO01vZHVsZVsiX3NrYWluZXRfcTVfMF9tYXRtdWxfcm0iXT1fc2thaW5ldF9xNV8wX21hdG11bF9ybT13YXNtRXhwb3J0c1sibSJdO01vZHVsZVsiX3NrYWluZXRfcTVfMV9tYXRtdWwiXT1fc2thaW5ldF9xNV8xX21hdG11bD13YXNtRXhwb3J0c1sibiJdO01vZHVsZVsiX3NrYWluZXRfcTVfMV9tYXRtdWxfcm0iXT1fc2thaW5ldF9xNV8xX21hdG11bF9ybT13YXNtRXhwb3J0c1sibyJdO01vZHVsZVsiX3NrYWluZXRfcThfMF9tYXRtdWwiXT1fc2thaW5ldF9xOF8wX21hdG11bD13YXNtRXhwb3J0c1sicCJdO01vZHVsZVsiX3NrYWluZXRfcThfMF9tYXRtdWxfcm0iXT1fc2thaW5ldF9xOF8wX21hdG11bF9ybT13YXNtRXhwb3J0c1sicSJdO01vZHVsZVsiX3NrYWluZXRfcTRrX21hdG11bCJdPV9za2FpbmV0X3E0a19tYXRtdWw9d2FzbUV4cG9ydHNbInIiXTtNb2R1bGVbIl9za2FpbmV0X3E0a19tYXRtdWxfcm0iXT1fc2thaW5ldF9xNGtfbWF0bXVsX3JtPXdhc21FeHBvcnRzWyJzIl07TW9kdWxlWyJfc2thaW5ldF9xNWtfbWF0bXVsIl09X3NrYWluZXRfcTVrX21hdG11bD13YXNtRXhwb3J0c1sidCJdO01vZHVsZVsiX3NrYWluZXRfcTVrX21hdG11bF9ybSJdPV9za2FpbmV0X3E1a19tYXRtdWxfcm09d2FzbUV4cG9ydHNbInUiXTtNb2R1bGVbIl9za2FpbmV0X3E2a19tYXRtdWwiXT1fc2thaW5ldF9xNmtfbWF0bXVsPXdhc21FeHBvcnRzWyJ2Il07TW9kdWxlWyJfc2thaW5ldF9xNmtfbWF0bXVsX3JtIl09X3NrYWluZXRfcTZrX21hdG11bF9ybT13YXNtRXhwb3J0c1sidyJdfXZhciB3YXNtSW1wb3J0cz17YTpfZW1zY3JpcHRlbl9yZXNpemVfaGVhcH07ZnVuY3Rpb24gYXBwbHlTaWduYXR1cmVDb252ZXJzaW9ucyh3YXNtRXhwb3J0cyl7d2FzbUV4cG9ydHM9T2JqZWN0LmFzc2lnbih7fSx3YXNtRXhwb3J0cyk7dmFyIG1ha2VXcmFwcGVyX3BwPWY9PmEwPT5mKGEwKT4+PjA7dmFyIG1ha2VXcmFwcGVyX3A9Zj0+KCk9PmYoKT4+PjA7d2FzbUV4cG9ydHNbImsiXT1tYWtlV3JhcHBlcl9wcCh3YXNtRXhwb3J0c1siayJdKTt3YXNtRXhwb3J0c1siX2Vtc2NyaXB0ZW5fc3RhY2tfYWxsb2MiXT1tYWtlV3JhcHBlcl9wcCh3YXNtRXhwb3J0c1siX2Vtc2NyaXB0ZW5fc3RhY2tfYWxsb2MiXSk7d2FzbUV4cG9ydHNbImVtc2NyaXB0ZW5fc3RhY2tfZ2V0X2N1cnJlbnQiXT1tYWtlV3JhcHBlcl9wKHdhc21FeHBvcnRzWyJlbXNjcmlwdGVuX3N0YWNrX2dldF9jdXJyZW50Il0pO3JldHVybiB3YXNtRXhwb3J0c31mdW5jdGlvbiBydW4oKXtwcmVSdW4oKTtmdW5jdGlvbiBkb1J1bigpe01vZHVsZVsiY2FsbGVkUnVuIl09dHJ1ZTtpZihBQk9SVClyZXR1cm47aW5pdFJ1bnRpbWUoKTtyZWFkeVByb21pc2VSZXNvbHZlPy4oTW9kdWxlKTtNb2R1bGVbIm9uUnVudGltZUluaXRpYWxpemVkIl0/LigpO3Bvc3RSdW4oKX1pZihNb2R1bGVbInNldFN0YXR1cyJdKXtNb2R1bGVbInNldFN0YXR1cyJdKCJSdW5uaW5nLi4uIik7c2V0VGltZW91dCgoKT0+e3NldFRpbWVvdXQoKCk9Pk1vZHVsZVsic2V0U3RhdHVzIl0oIiIpLDEpO2RvUnVuKCl9LDEpfWVsc2V7ZG9SdW4oKX19dmFyIHdhc21FeHBvcnRzO3dhc21FeHBvcnRzPWF3YWl0IChjcmVhdGVXYXNtKCkpO3J1bigpO2lmKHJ1bnRpbWVJbml0aWFsaXplZCl7bW9kdWxlUnRuPU1vZHVsZX1lbHNle21vZHVsZVJ0bj1uZXcgUHJvbWlzZSgocmVzb2x2ZSxyZWplY3QpPT57cmVhZHlQcm9taXNlUmVzb2x2ZT1yZXNvbHZlO3JlYWR5UHJvbWlzZVJlamVjdD1yZWplY3R9KX0KO3JldHVybiBtb2R1bGVSdG59ZXhwb3J0IGRlZmF1bHQgY3JlYXRlU2thaW5ldEtlcm5lbHM7Cg==" - const val ST_WASM: String = "AGFzbQEAAAABTgpgA39/fwBgCH9/f39/f39/AGABfwF/YAl/f39/f39/f38AYAx/f39/f39/f39/f38AYAAAYAF/AGAEf399fwF9YAJ/fwF9YAN/f30BfQIHAQFhAWEAAgMuLQACBgIDAwUHCAkAAQABBAIEAAEAAQABAAABAAEAAQABAAMBAAEAAQABAAEEBQQFAXABEhIFBwEBgAiAgAQGCAF/AUGgjQQLB1kWAWICAAFjAC0BZAAsAWUAIgFmABEBZwAPAWgADgFpAAwBagArAWsABAFsAAMBbQApAW4AJwFvACUBcAAjAXEAIAFyAB4BcwAcAXQAGgF1ABcBdgAVAXcAEwkXAQBBAQsRGQ0LKigmJCEfHRsYFhQSBxAMAQEKy5QCLZUDAQV/AkAgAkEASgRAIAJB/wNNDQFBhAgoAgBB37femgFHBEAQB0GECEHft96aATYCAAsCQEGoCSgCACIDBEBBpAkoAgBFDQELDAILQZgJIAM2AgBBiAkgAjYCAEGECSABNgIAQYAJIAA2AgBBpAlBATYCAEGMCSADQQFqIgM2AgBBlAlBlAkoAgBBAWo2AgBBkAlBADYCAEGcCSgCAARAQYwJKAIAIQMLIAJBkAkoAgAiBEoEQCADQQF0IQYDQEGQCUHAACACIARrIAZtIgMgA0HAAEwbIARqIgVBkAkoAgAiAyADIARGIgcbNgIAIAcEfyABIAQgBSACIAIgBUobIAARAABBkAkoAgAFIAMLIgQgAkgNAAsLQZgJKAIAQQBMIQBBACEEAkADQCAADQFBmAkoAgBBAEwiAQ0BIAENASABDQEgBEEEaiIEQYCAwABHDQALQaAJQQE2AgBBmAkoAgBBAEoEQANAQZgJKAIAQQBKDQALC0GgCUEANgIAC0GkCUEANgIACw8LIAFBACACIAARAAALTwECf0GACCgCACIBIABBB2pBeHEiAmohAAJAIAJBACAAIAFNG0UEQCAAPwBBEHRNDQEgABAADQELQawJQTA2AgBBfw8LQYAIIAA2AgAgAQvfCwEIfwJAIABFDQAgAEEIayIDIABBBGsoAgAiAkF4cSIAaiEFAkAgAkEBcQ0AIAJBAnFFDQEgAyADKAIAIgRrIgNBwAkoAgBJDQEgACAEaiEAAkACQAJAQcQJKAIAIANHBEAgAygCDCEBIARB/wFNBEAgASADKAIIIgJHDQJBsAlBsAkoAgBBfiAEQQN2d3E2AgAMBQsgAygCGCEHIAEgA0cEQCADKAIIIgIgATYCDCABIAI2AggMBAsgAygCFCICBH8gA0EUagUgAygCECICRQ0DIANBEGoLIQQDQCAEIQYgAiIBQRRqIQQgASgCFCICDQAgAUEQaiEEIAEoAhAiAg0ACyAGQQA2AgAMAwsgBSgCBCICQQNxQQNHDQNBuAkgADYCACAFIAJBfnE2AgQgAyAAQQFyNgIEIAUgADYCAA8LIAIgATYCDCABIAI2AggMAgtBACEBCyAHRQ0AAkAgAygCHCIEQQJ0IgIoAuALIANGBEAgAkHgC2ogATYCACABDQFBtAlBtAkoAgBBfiAEd3E2AgAMAgsCQCADIAcoAhBGBEAgByABNgIQDAELIAcgATYCFAsgAUUNAQsgASAHNgIYIAMoAhAiAgRAIAEgAjYCECACIAE2AhgLIAMoAhQiAkUNACABIAI2AhQgAiABNgIYCyADIAVPDQAgBSgCBCIEQQFxRQ0AAkACQAJAAkAgBEECcUUEQEHICSgCACAFRgRAQcgJIAM2AgBBvAlBvAkoAgAgAGoiADYCACADIABBAXI2AgQgA0HECSgCAEcNBkG4CUEANgIAQcQJQQA2AgAPC0HECSgCACIHIAVGBEBBxAkgAzYCAEG4CUG4CSgCACAAaiIANgIAIAMgAEEBcjYCBCAAIANqIAA2AgAPCyAEQXhxIABqIQAgBSgCDCEBIARB/wFNBEAgBSgCCCICIAFGBEBBsAlBsAkoAgBBfiAEQQN2d3E2AgAMBQsgAiABNgIMIAEgAjYCCAwECyAFKAIYIQggASAFRwRAIAUoAggiAiABNgIMIAEgAjYCCAwDCyAFKAIUIgIEfyAFQRRqBSAFKAIQIgJFDQIgBUEQagshBANAIAQhBiACIgFBFGohBCABKAIUIgINACABQRBqIQQgASgCECICDQALIAZBADYCAAwCCyAFIARBfnE2AgQgAyAAQQFyNgIEIAAgA2ogADYCAAwDC0EAIQELIAhFDQACQCAFKAIcIgRBAnQiAigC4AsgBUYEQCACQeALaiABNgIAIAENAUG0CUG0CSgCAEF+IAR3cTYCAAwCCwJAIAUgCCgCEEYEQCAIIAE2AhAMAQsgCCABNgIUCyABRQ0BCyABIAg2AhggBSgCECICBEAgASACNgIQIAIgATYCGAsgBSgCFCICRQ0AIAEgAjYCFCACIAE2AhgLIAMgAEEBcjYCBCAAIANqIAA2AgAgAyAHRw0AQbgJIAA2AgAPCyAAQf8BTQRAIABB+AFxQdgJaiECAn9BsAkoAgAiBEEBIABBA3Z0IgBxRQRAQbAJIAAgBHI2AgAgAgwBCyACKAIICyEAIAIgAzYCCCAAIAM2AgwgAyACNgIMIAMgADYCCA8LQR8hASAAQf///wdNBEAgAEEmIABBCHZnIgJrdkEBcSACQQF0a0E+aiEBCyADIAE2AhwgA0IANwIQIAFBAnRB4AtqIQQCfwJAAn9BtAkoAgAiBkEBIAF0IgJxRQRAQbQJIAIgBnI2AgAgBCADNgIAQRghAUEIDAELIABBGSABQQF2a0EAIAFBH0cbdCEBIAQoAgAhBANAIAQiAigCBEF4cSAARg0CIAFBHXYhBCABQQF0IQEgAiAEQQRxaiIGKAIQIgQNAAsgBiADNgIQQRghASACIQRBCAshACADIgIMAQsgAigCCCIEIAM2AgwgAiADNgIIQRghAEEIIQFBAAshBiABIANqIAQ2AgAgAyACNgIMIAAgA2ogBjYCAEHQCUHQCSgCAEEBayIAQX8gABs2AgALC8EnAQt/IwBBEGsiCiQAAkACQAJAAkACQAJAAkACQAJAAkAgAEH0AU0EQEGwCSgCACIEQRAgAEELakH4A3EgAEELSRsiBkEDdiIAdiIBQQNxBEACQCABQX9zQQFxIABqIgNBA3QiAUHYCWoiACABKALgCSICKAIIIgVGBEBBsAkgBEF+IAN3cTYCAAwBCyAFIAA2AgwgACAFNgIICyACQQhqIQAgAiABQQNyNgIEIAEgAmoiASABKAIEQQFyNgIEDAsLIAZBuAkoAgAiCE0NASABBEACQEECIAB0IgJBACACa3IgASAAdHFoIgNBA3QiAUHYCWoiAiABKALgCSIAKAIIIgVGBEBBsAkgBEF+IAN3cSIENgIADAELIAUgAjYCDCACIAU2AggLIAAgBkEDcjYCBCAAIAZqIgcgASAGayIFQQFyNgIEIAAgAWogBTYCACAIBEAgCEF4cUHYCWohAUHECSgCACECAn8gBEEBIAhBA3Z0IgNxRQRAQbAJIAMgBHI2AgAgAQwBCyABKAIICyEDIAEgAjYCCCADIAI2AgwgAiABNgIMIAIgAzYCCAsgAEEIaiEAQcQJIAc2AgBBuAkgBTYCAAwLC0G0CSgCACILRQ0BIAtoQQJ0KALgCyICKAIEQXhxIAZrIQMgAiEBA0ACQCABKAIQIgBFBEAgASgCFCIARQ0BCyAAKAIEQXhxIAZrIgEgAyABIANJIgEbIQMgACACIAEbIQIgACEBDAELCyACKAIYIQkgAiACKAIMIgBHBEAgAigCCCIBIAA2AgwgACABNgIIDAoLIAIoAhQiAQR/IAJBFGoFIAIoAhAiAUUNAyACQRBqCyEFA0AgBSEHIAEiAEEUaiEFIAAoAhQiAQ0AIABBEGohBSAAKAIQIgENAAsgB0EANgIADAkLQX8hBiAAQb9/Sw0AIABBC2oiAUF4cSEGQbQJKAIAIgdFDQBBHyEIQQAgBmshAyAAQfT//wdNBEAgBkEmIAFBCHZnIgBrdkEBcSAAQQF0a0E+aiEICwJAAkACQCAIQQJ0KALgCyIBRQRAQQAhAAwBC0EAIQAgBkEZIAhBAXZrQQAgCEEfRxt0IQIDQAJAIAEoAgRBeHEgBmsiBCADTw0AIAEhBSAEIgMNAEEAIQMgASEADAMLIAAgASgCFCIEIAQgASACQR12QQRxaigCECIBRhsgACAEGyEAIAJBAXQhAiABDQALCyAAIAVyRQRAQQAhBUECIAh0IgBBACAAa3IgB3EiAEUNAyAAaEECdCgC4AshAAsgAEUNAQsDQCAAKAIEQXhxIAZrIgIgA0khASACIAMgARshAyAAIAUgARshBSAAKAIQIgEEfyABBSAAKAIUCyIADQALCyAFRQ0AIANBuAkoAgAgBmtPDQAgBSgCGCEIIAUgBSgCDCIARwRAIAUoAggiASAANgIMIAAgATYCCAwICyAFKAIUIgEEfyAFQRRqBSAFKAIQIgFFDQMgBUEQagshAgNAIAIhBCABIgBBFGohAiAAKAIUIgENACAAQRBqIQIgACgCECIBDQALIARBADYCAAwHCyAGQbgJKAIAIgVNBEBBxAkoAgAhAAJAIAUgBmsiAUEQTwRAIAAgBmoiAiABQQFyNgIEIAAgBWogATYCACAAIAZBA3I2AgQMAQsgACAFQQNyNgIEIAAgBWoiASABKAIEQQFyNgIEQQAhAkEAIQELQbgJIAE2AgBBxAkgAjYCACAAQQhqIQAMCQsgBkG8CSgCACICSQRAQbwJIAIgBmsiATYCAEHICUHICSgCACIAIAZqIgI2AgAgAiABQQFyNgIEIAAgBkEDcjYCBCAAQQhqIQAMCQtBACEAIAZBL2oiAwJ/QYgNKAIABEBBkA0oAgAMAQtBlA1CfzcCAEGMDUKAoICAgIAENwIAQYgNIApBDGpBcHFB2KrVqgVzNgIAQZwNQQA2AgBB7AxBADYCAEGAIAsiAWoiBEEAIAFrIgdxIgEgBk0NCEHoDCgCACIFBEBB4AwoAgAiCCABaiIJIAhNDQkgBSAJSQ0JCwJAQewMLQAAQQRxRQRAAkACQAJAAkBByAkoAgAiBQRAQfAMIQADQCAAKAIAIgggBU0EQCAFIAggACgCBGpJDQMLIAAoAggiAA0ACwtBABACIgJBf0YNAyABIQRBjA0oAgAiAEEBayIFIAJxBEAgASACayACIAVqQQAgAGtxaiEECyAEIAZNDQNB6AwoAgAiAARAQeAMKAIAIgUgBGoiByAFTQ0EIAAgB0kNBAsgBBACIgAgAkcNAQwFCyAEIAJrIAdxIgQQAiICIAAoAgAgACgCBGpGDQEgAiEACyAAQX9GDQEgBkEwaiAETQRAIAAhAgwEC0GQDSgCACICIAMgBGtqQQAgAmtxIgIQAkF/Rg0BIAIgBGohBCAAIQIMAwsgAkF/Rw0CC0HsDEHsDCgCAEEEcjYCAAsgARACIQJBABACIQAgAkF/Rg0FIABBf0YNBSAAIAJNDQUgACACayIEIAZBKGpNDQULQeAMQeAMKAIAIARqIgA2AgBB5AwoAgAgAEkEQEHkDCAANgIACwJAQcgJKAIAIgMEQEHwDCEAA0AgAiAAKAIAIgEgACgCBCIFakYNAiAAKAIIIgANAAsMBAtBwAkoAgAiAEEAIAAgAk0bRQRAQcAJIAI2AgALQQAhAEH0DCAENgIAQfAMIAI2AgBB0AlBfzYCAEHUCUGIDSgCADYCAEH8DEEANgIAA0AgAEEDdCIBIAFB2AlqIgU2AuAJIAEgBTYC5AkgAEEBaiIAQSBHDQALQbwJIARBKGsiAEF4IAJrQQdxIgFrIgU2AgBByAkgASACaiIBNgIAIAEgBUEBcjYCBCAAIAJqQSg2AgRBzAlBmA0oAgA2AgAMBAsgAiADTQ0CIAEgA0sNAiAAKAIMQQhxDQIgACAEIAVqNgIEQcgJIANBeCADa0EHcSIAaiIBNgIAQbwJQbwJKAIAIARqIgIgAGsiADYCACABIABBAXI2AgQgAiADakEoNgIEQcwJQZgNKAIANgIADAMLQQAhAAwGC0EAIQAMBAtBwAkoAgAgAksEQEHACSACNgIACyACIARqIQVB8AwhAAJAA0AgBSAAKAIAIgFHBEAgACgCCCIADQEMAgsLIAAtAAxBCHFFDQMLQfAMIQADQAJAIAAoAgAiASADTQRAIAMgASAAKAIEaiIFSQ0BCyAAKAIIIQAMAQsLQbwJIARBKGsiAEF4IAJrQQdxIgFrIgc2AgBByAkgASACaiIBNgIAIAEgB0EBcjYCBCAAIAJqQSg2AgRBzAlBmA0oAgA2AgAgAyAFQScgBWtBB3FqQS9rIgAgACADQRBqSRsiAUEbNgIEIAFB+AwpAgA3AhAgAUHwDCkCADcCCEH4DCABQQhqNgIAQfQMIAQ2AgBB8AwgAjYCAEH8DEEANgIAIAFBGGohAANAIABBBzYCBCAAQQhqIABBBGohACAFSQ0ACyABIANGDQAgASABKAIEQX5xNgIEIAMgASADayICQQFyNgIEIAEgAjYCAAJ/IAJB/wFNBEAgAkH4AXFB2AlqIQACf0GwCSgCACIBQQEgAkEDdnQiAnFFBEBBsAkgASACcjYCACAADAELIAAoAggLIQEgACADNgIIIAEgAzYCDEEMIQJBCAwBC0EfIQAgAkH///8HTQRAIAJBJiACQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAAsgAyAANgIcIANCADcCECAAQQJ0QeALaiEBAkACQEG0CSgCACIFQQEgAHQiBHFFBEBBtAkgBCAFcjYCACABIAM2AgAMAQsgAkEZIABBAXZrQQAgAEEfRxt0IQAgASgCACEFA0AgBSIBKAIEQXhxIAJGDQIgAEEddiEFIABBAXQhACABIAVBBHFqIgQoAhAiBQ0ACyAEIAM2AhALIAMgATYCGEEIIQIgAyIBIQBBDAwBCyABKAIIIgAgAzYCDCABIAM2AgggAyAANgIIQQAhAEEYIQJBDAsgA2ogATYCACACIANqIAA2AgALQbwJKAIAIgAgBk0NAEG8CSAAIAZrIgE2AgBByAlByAkoAgAiACAGaiICNgIAIAIgAUEBcjYCBCAAIAZBA3I2AgQgAEEIaiEADAQLQawJQTA2AgBBACEADAMLIAAgAjYCACAAIAAoAgQgBGo2AgQgAkF4IAJrQQdxaiIIIAZBA3I2AgQgAUF4IAFrQQdxaiIEIAYgCGoiA2shBwJAQcgJKAIAIARGBEBByAkgAzYCAEG8CUG8CSgCACAHaiIANgIAIAMgAEEBcjYCBAwBC0HECSgCACAERgRAQcQJIAM2AgBBuAlBuAkoAgAgB2oiADYCACADIABBAXI2AgQgACADaiAANgIADAELIAQoAgQiAEEDcUEBRgRAIABBeHEhCSAEKAIMIQICQCAAQf8BTQRAIAQoAggiASACRgRAQbAJQbAJKAIAQX4gAEEDdndxNgIADAILIAEgAjYCDCACIAE2AggMAQsgBCgCGCEGAkAgAiAERwRAIAQoAggiACACNgIMIAIgADYCCAwBCwJAIAQoAhQiAAR/IARBFGoFIAQoAhAiAEUNASAEQRBqCyEBA0AgASEFIAAiAkEUaiEBIAAoAhQiAA0AIAJBEGohASACKAIQIgANAAsgBUEANgIADAELQQAhAgsgBkUNAAJAIAQoAhwiAEECdCIBKALgCyAERgRAIAFB4AtqIAI2AgAgAg0BQbQJQbQJKAIAQX4gAHdxNgIADAILAkAgBCAGKAIQRgRAIAYgAjYCEAwBCyAGIAI2AhQLIAJFDQELIAIgBjYCGCAEKAIQIgAEQCACIAA2AhAgACACNgIYCyAEKAIUIgBFDQAgAiAANgIUIAAgAjYCGAsgByAJaiEHIAQgCWoiBCgCBCEACyAEIABBfnE2AgQgAyAHQQFyNgIEIAMgB2ogBzYCACAHQf8BTQRAIAdB+AFxQdgJaiEAAn9BsAkoAgAiAUEBIAdBA3Z0IgJxRQRAQbAJIAEgAnI2AgAgAAwBCyAAKAIICyEBIAAgAzYCCCABIAM2AgwgAyAANgIMIAMgATYCCAwBC0EfIQIgB0H///8HTQRAIAdBJiAHQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAgsgAyACNgIcIANCADcCECACQQJ0QeALaiEAAkACQEG0CSgCACIBQQEgAnQiBXFFBEBBtAkgASAFcjYCACAAIAM2AgAMAQsgB0EZIAJBAXZrQQAgAkEfRxt0IQIgACgCACEBA0AgASIAKAIEQXhxIAdGDQIgAkEddiEBIAJBAXQhAiAAIAFBBHFqIgUoAhAiAQ0ACyAFIAM2AhALIAMgADYCGCADIAM2AgwgAyADNgIIDAELIAAoAggiASADNgIMIAAgAzYCCCADQQA2AhggAyAANgIMIAMgATYCCAsgCEEIaiEADAILAkAgCEUNAAJAIAUoAhwiAUECdCICKALgCyAFRgRAIAJB4AtqIAA2AgAgAA0BQbQJIAdBfiABd3EiBzYCAAwCCwJAIAUgCCgCEEYEQCAIIAA2AhAMAQsgCCAANgIUCyAARQ0BCyAAIAg2AhggBSgCECIBBEAgACABNgIQIAEgADYCGAsgBSgCFCIBRQ0AIAAgATYCFCABIAA2AhgLAkAgA0EPTQRAIAUgAyAGaiIAQQNyNgIEIAAgBWoiACAAKAIEQQFyNgIEDAELIAUgBkEDcjYCBCAFIAZqIgQgA0EBcjYCBCADIARqIAM2AgAgA0H/AU0EQCADQfgBcUHYCWohAAJ/QbAJKAIAIgFBASADQQN2dCICcUUEQEGwCSABIAJyNgIAIAAMAQsgACgCCAshASAAIAQ2AgggASAENgIMIAQgADYCDCAEIAE2AggMAQtBHyEAIANB////B00EQCADQSYgA0EIdmciAGt2QQFxIABBAXRrQT5qIQALIAQgADYCHCAEQgA3AhAgAEECdEHgC2ohAQJAAkAgB0EBIAB0IgJxRQRAQbQJIAIgB3I2AgAgASAENgIAIAQgATYCGAwBCyADQRkgAEEBdmtBACAAQR9HG3QhACABKAIAIQEDQCABIgIoAgRBeHEgA0YNAiAAQR12IQEgAEEBdCEAIAIgAUEEcWoiBygCECIBDQALIAcgBDYCECAEIAI2AhgLIAQgBDYCDCAEIAQ2AggMAQsgAigCCCIAIAQ2AgwgAiAENgIIIARBADYCGCAEIAI2AgwgBCAANgIICyAFQQhqIQAMAQsCQCAJRQ0AAkAgAigCHCIBQQJ0IgUoAuALIAJGBEAgBUHgC2ogADYCACAADQFBtAkgC0F+IAF3cTYCAAwCCwJAIAIgCSgCEEYEQCAJIAA2AhAMAQsgCSAANgIUCyAARQ0BCyAAIAk2AhggAigCECIBBEAgACABNgIQIAEgADYCGAsgAigCFCIBRQ0AIAAgATYCFCABIAA2AhgLAkAgA0EPTQRAIAIgAyAGaiIAQQNyNgIEIAAgAmoiACAAKAIEQQFyNgIEDAELIAIgBkEDcjYCBCACIAZqIgUgA0EBcjYCBCADIAVqIAM2AgAgCARAIAhBeHFB2AlqIQBBxAkoAgAhAQJ/QQEgCEEDdnQiByAEcUUEQEGwCSAEIAdyNgIAIAAMAQsgACgCCAshBCAAIAE2AgggBCABNgIMIAEgADYCDCABIAQ2AggLQcQJIAU2AgBBuAkgAzYCAAsgAkEIaiEACyAKQRBqJAAgAAvdBAMCewd/AX0jAEEgayILJAACQCAEQQBMDQAgBUEATA0AIAQQBCEMIARBCHYiDkECdBAEIQ0CQCAMRQ0AIA1FDQAgBEGAAk8EQCAAIAFBAnRqIRBBACEAA0AgAEEIdCERIBAgAEEKdGohD/0MAAAAAAAAAAAAAAAAAAAAACEJQQAhAQNAIA8gAUECdGoiBP0AAjD94AEgBP0AAiD94AEgBP0AAhD94AEgBP0AAgD94AEgCf3rAf3rAf3rAf3rASEJIAFBEGoiAUGAAkcNAAsgDCARaiEBIA0gAEECdGoCfSAJIAkgCf0NCAkKCwwNDg8AAQIDAAECA/3rASIJIAkgCf0NBAUGBwABAgMAAQIDAAECA/3rAf0fACISQwAAAABcBEBDAACAPyASlf0TIQpBACEEA0AgASAEaiAPIARBAnRq/QACAP0MAAD+QgAA/kIAAP5CAAD+Qv3mASAK/eYBIgn9HwCQ/AD9ESAJ/R8BkPwA/RwBIAn9HwKQ/AD9HAIgCf0fA5D8AP0cA/0Mgf///4H///+B////gf////24Af0MfwAAAH8AAAB/AAAAfwAAAP22ASAJ/Q0ABAgMAAAAAAAAAAAAAAAA/VoAAAAgBEEEaiIEQYACRw0ACyASQwQCATyUDAELIAFBAEGAAvwLAEMAAAAACzgCACAAQQFqIgAgDkcNAAsLIAtBADYCHCALIAU2AhggCyAONgIUIAsgDTYCDCALIAw2AgggCyACIANqNgIEIAsgBiAHQQJ0ajYCECAIIAtBBGogBRABCyAMEAMgDRADCyALQSBqJAALqAICAn8BeyMAQSBrIgkkAAJAIAVBAEwNACAEQQBMBEAgBUECdCIARQ0BIAYgB0ECdGpBACAA/AsADAELIAkgBTYCHCAJIARBBXYiCjYCGCAJIAIgA2o2AgggCSAGIAdBAnRqNgIQIAkgACABQQJ0aiICNgIMIApBAnQQBCIBRQ0AIARBH0sEQEEAIQcDQCABIAdBAnRqIAIgB0EHdGoiAP0AAgAgAP0AAnD95AEgAP0AAkD95AEgAP0AAiAgAP0AAmD95AH95AEgAP0AAhAgAP0AAlD95AEgAP0AAjD95AH95AEiC/0fACAL/R8BkiAL/R8CkiAL/R8DkjgCACAHQQFqIgcgCkcNAAsLIAkgATYCFCAIIAlBCGogBRABIAEQAwsgCUEgaiQACxQBAX8jAEEQayIAJAAgAEEQaiQAC4ITBAN7Bn8BfQF+IAAtANEBIghBB3YhByAIQQh0IgogAC0A0AFyQf8HcSEJAn0CQCAIQQJ2QR9xIghBH0cEQCAIDQEgB0EfdL4gCUUNAhogCbNDAACAM5QiDYwgDSAKwUEASBsMAgsgB0EfdEGAgIACQQAgCRtyQYCAgPwHcr4MAQsgCEEXdCAHQR90ciAJQQ10ckGAgIDAA2q+CyAA/QAAICEFIAMgAP0AAIABIgT9DDAwMDAwMDAwMDAwMDAwMDD9TiAA/QAAACIGQQT9bf1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwBAIAMgBEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9TiAFQQT9bf1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwBgIAMgBEEC/Wv9DDAwMDAwMDAwMDAwMDAwMDD9TiAF/QwPDw8PDw8PDw8PDw8PDw8P/U79UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAICADIARBBP1r/QwwMDAwMDAwMDAwMDAwMDAw/U4gBv0MDw8PDw8PDw8PDw8PDw8PD/1O/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAAAgAP0AADAhBSADIAD9AACQASIE/QwwMDAwMDAwMDAwMDAwMDAw/U4gAP0AABAiBkEE/W39UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAUCADIARBAv1t/QwwMDAwMDAwMDAwMDAwMDAw/U4gBUEE/W39UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAcCADIARBAv1r/QwwMDAwMDAwMDAwMDAwMDAw/U4gBf0MDw8PDw8PDw8PDw8PDw8PD/1O/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LADAgAyAEQQT9a/0MMDAwMDAwMDAwMDAwMDAwMP1OIAb9DA8PDw8PDw8PDw8PDw8PDw/9Tv1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwAQIAD9AABgIQUgAyAA/QAAoAEiBP0MMDAwMDAwMDAwMDAwMDAwMP1OIAD9AABAIgZBBP1t/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAMABIAMgBEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9TiAFQQT9bf1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwDgASADIARBAv1r/QwwMDAwMDAwMDAwMDAwMDAw/U4gBf0MDw8PDw8PDw8PDw8PDw8PD/1O/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAKABIAMgBEEE/Wv9DDAwMDAwMDAwMDAwMDAwMDD9TiAG/QwPDw8PDw8PDw8PDw8PDw8P/U79UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAgAEgAP0AAHAhBSADIAD9AACwASIE/QwwMDAwMDAwMDAwMDAwMDAw/U4gAP0AAFAiBkEE/W39UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsA0AEgAyAEQQL9bf0MMDAwMDAwMDAwMDAwMDAwMP1OIAVBBP1t/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAPABIAMgBEEC/Wv9DDAwMDAwMDAwMDAwMDAwMDD9TiAF/QwPDw8PDw8PDw8PDw8PDw8P/U79UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAsAEgAyAEQQT9a/0MMDAwMDAwMDAwMDAwMDAwMP1OIAb9DA8PDw8PDw8PDw8PDw8PDw/9Tv1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwCQASAAQcABaiEIQQAhAEEBIQkDQCAAQQd0IQogCCAAQQN0aiELQQAhAANAIAsgAEEBdGoiDDAAACADIABBBXQgCmoiB2r9AAAAIgT9hwH9pwEgASAHav0AAAAiBf2HAf2nAf3cASAEIAT9DQgJAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0ICQAAAAAAAAAAAAAAAAAA/YcB/acB/dwB/c4BIAQgBP0NBAUAAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQQFAAAAAAAAAAAAAAAAAAD9hwH9pwH93AEgBCAE/Q0MDQAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NDA0AAAAAAAAAAAAAAAAAAP2HAf2nAf3cAf3OAf3OASAEIAT9DQIDAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0CAwAAAAAAAAAAAAAAAAAA/YcB/acB/dwBIAQgBP0NCgsAAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQoLAAAAAAAAAAAAAAAAAAD9hwH9pwH93AH9zgEgBCAE/Q0GBwAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NBgcAAAAAAAAAAAAAAAAAAP2HAf2nAf3cASAEIAT9DQ4PAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0ODwAAAAAAAAAAAAAAAAAA/YcB/acB/dwB/c4B/c4B/c4BIgQgBCAE/Q0ICQoLDA0ODwABAgMEBQYH/c4B/R0AfiAOfCAMMAABIAMgB0EQciIHav0AAAAiBP2HAf2nASABIAdq/QAAACIF/YcB/acB/dwBIAQgBP0NCAkAAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQgJAAAAAAAAAAAAAAAAAAD9hwH9pwH93AH9zgEgBCAE/Q0EBQAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NBAUAAAAAAAAAAAAAAAAAAP2HAf2nAf3cASAEIAT9DQwNAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0MDQAAAAAAAAAAAAAAAAAA/YcB/acB/dwB/c4B/c4BIAQgBP0NAgMAAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQIDAAAAAAAAAAAAAAAAAAD9hwH9pwH93AEgBCAE/Q0KCwAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NCgsAAAAAAAAAAAAAAAAAAP2HAf2nAf3cAf3OASAEIAT9DQYHAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0GBwAAAAAAAAAAAAAAAAAA/YcB/acB/dwBIAQgBP0NDg8AAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQ4PAAAAAAAAAAAAAAAAAAD9hwH9pwH93AH9zgH9zgH9zgEiBCAEIAT9DQgJCgsMDQ4PAAECAwQFBgf9zgH9HQB+fCEOIABBAWoiAEEERw0AC0EBIQAgCUEAIQkNAAsgApQgDrSUC+Q1Axp7Bn8CfSAALQABIh9BB3YhHSAALQADQQh0IiAgAC0AAnIhHiAfQQh0IiEgAC0AAHJB/wdxIRwCfQJAIB9BAnZBH3EiH0EfRwRAIB8NASAdQR90viAcRQ0CGiAcs0MAAIAzlCIijCAiICHBQQBIGwwCCyAdQR90QYCAgAJBACAcG3JBgICA/AdyvgwBCyAfQRd0IB1BH3RyIBxBDXRyQYCAgMADar4LISMgHkH/B3EhHCAeQYCAAnFBD3YhHSAB/QAC8AEiAyAA/VwALP2JAf2pASIEQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwATP2JAf2pASICQQT9rQH9UP36Af3mASAB/QAC4AEiBiAA/VwAKP2JAf2pASIOQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwASP2JAf2pASIHQQT9rQH9UP36Af3mASAB/QAC0AEiCCAA/VwAJP2JAf2pASIPQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwARP2JAf2pASIJQQT9rQH9UP36Af3mASAB/QACwAEiCiAA/VwAIP2JAf2pASIQQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAQP2JAf2pASILQQT9rQH9UP36Af3mASAB/QACsAEiDCAA/VwAHP2JAf2pASIRQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAPP2JAf2pASIFQQT9rQH9UP36Af3mASAB/QACoAEiFSAA/VwAGP2JAf2pASISQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAOP2JAf2pASIWQQT9rQH9UP36Af3mASAB/QACkAEiFyAA/VwAFP2JAf2pASITQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwANP2JAf2pASIYQQT9rQH9UP36Af3mASAB/QACgAEiGSAA/VwAEP2JAf2pASIaQQP9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAMP2JAf2pASIbQQT9rQH9UP36Af3mAf3kAf3kAf3kAf3kAf3kAf3kAf3kASIUIBT9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiFCAU/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQBIAMgBiAIIAogDCAVIBcgGf3kAf3kAf3kAf3kAf3kAf3kAf3kASIDIAP9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiAyAD/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AAn0CQCAeQQp2QR9xIh5BH0cEQCAeDQEgHUEfdL4gHEUNAhogHLNDAACAM5QiIowgIiAgwUEASBsMAgsgHUEfdEGAgIACQQAgHBtyQYCAgPwHcr4MAQsgHkEXdCAdQR90ciAcQQ10ckGAgIDAA2q+CyIilP0gASAA/V0ABCID/RYBQT9xsv0TIAP9FgVBP3Gy/SAB/eYBIAH9AAJwIgYgBEEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAv0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAmAiAiAOQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAH/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACUCIHIA9BBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAn9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAJAIgggEEEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gC/0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAjAiCSARQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAF/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACICIKIBJBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBb9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAIQIgsgE0EE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gGP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAgAiDCAaQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAb/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mAf3kAf3kAf3kAf3kAf3kAf3kAf3kASIFIAX9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiBSAF/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQBIAYgAiAHIAggCSAKIAsgDP3kAf3kAf3kAf3kAf3kAf3kAf3kASICIAL9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AICKU/SABIAP9FgBBP3Gy/RMgA/0WBEE/cbL9IAH95gH95AEgAf0AAvADIgIgBEEB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAGz9iQH9qQEiBkEE/a0B/VD9+gH95gEgAf0AAuADIgcgDkEB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAGj9iQH9qQEiCEEE/a0B/VD9+gH95gEgAf0AAtADIgkgD0EB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAGT9iQH9qQEiCkEE/a0B/VD9+gH95gEgAf0AAsADIgsgEEEB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAGD9iQH9qQEiDEEE/a0B/VD9+gH95gEgAf0AArADIgUgEUEB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAFz9iQH9qQEiFUEE/a0B/VD9+gH95gEgAf0AAqADIhYgEkEB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAFj9iQH9qQEiF0EE/a0B/VD9+gH95gEgAf0AApADIhggE0EB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAFT9iQH9qQEiGUEE/a0B/VD9+gH95gEgAf0AAoADIhsgGkEB/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAFD9iQH9qQEiFEEE/a0B/VD9+gH95gH95AH95AH95AH95AH95AH95AH95AEiDSAN/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIg0gDf0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kASACIAcgCSALIAUgFiAYIBv95AH95AH95AH95AH95AH95AH95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIgIgAv0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAilP0gASAD/RYDQT9xsv0TIAP9FgdBP3Gy/SAB/eYBIAH9AALwAiICIARBAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAb9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALgAiIGIA5BAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAj9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALQAiIHIA9BAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAr9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALAAiIIIBBBAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAz9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKwAiIJIBFBAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBX9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKgAiIKIBJBAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBf9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKQAiILIBNBAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBn9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKAAiIMIBpBAv2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBT9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYB/eQB/eQB/eQB/eQB/eQB/eQB/eQBIgUgBf0MEAAAABAAAAAQAAAAEAAAAP0NBAUGBwABAgMMDQ4PAAECA/3kASIFIAX9DBAAAAAQAAAAEAAAABAAAAD9DQgJCgsAAQIDAAECAwABAgP95AEgAiAGIAcgCCAJIAogCyAM/eQB/eQB/eQB/eQB/eQB/eQB/eQBIgIgAv0MEAAAABAAAAAQAAAAEAAAAP0NBAUGBwABAgMMDQ4PAAECA/3kASICIAL9DBAAAAAQAAAAEAAAABAAAAD9DQgJCgsAAQIDAAECAwABAgP95AH9HwAgIpT9IAEgA/0WAkE/cbL9EyAD/RYGQT9xsv0gAf3mAf3kAf3kASAB/QAC8AUiAiAEQQH9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAjAH9iQH9qQEiBkEE/a0B/VD9+gH95gEgAf0AAuAFIgcgDkEB/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAIgB/YkB/akBIghBBP2tAf1Q/foB/eYBIAH9AALQBSIJIA9BAf2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACEAf2JAf2pASIKQQT9rQH9UP36Af3mASAB/QACwAUiCyAQQQH9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAgAH9iQH9qQEiDEEE/a0B/VD9+gH95gEgAf0AArAFIgUgEUEB/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAHz9iQH9qQEiFUEE/a0B/VD9+gH95gEgAf0AAqAFIhYgEkEB/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAHj9iQH9qQEiF0EE/a0B/VD9+gH95gEgAf0AApAFIhggE0EB/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAHT9iQH9qQEiGUEE/a0B/VD9+gH95gEgAf0AAoAFIhsgGkEB/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAHD9iQH9qQEiFEEE/a0B/VD9+gH95gH95AH95AH95AH95AH95AH95AH95AEiDSAN/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIg0gDf0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kASACIAcgCSALIAUgFiAYIBv95AH95AH95AH95AH95AH95AH95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIgIgAv0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAilP0gASAALQANIhxBD3H9DyAcQQR2/RcBIAP9DBAAAAAQAAAAEAAAABAAAAD9DQEFAAAAAAAAAAAAAAAAAABBAv1t/QwwMDAwMDAwMDAwMDAwMDAw/U79UCIC/RYAsv0TIAL9FgGy/SAB/eYBIAH9AALwBCICIAT9DBAAAAAQAAAAEAAAABAAAAD9TiAG/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QAC4AQiBiAO/QwQAAAAEAAAABAAAAAQAAAA/U4gCP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAtAEIgcgD/0MEAAAABAAAAAQAAAAEAAAAP1OIAr9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALABCIIIBD9DBAAAAAQAAAAEAAAABAAAAD9TiAM/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACsAQiCSAR/QwQAAAAEAAAABAAAAAQAAAA/U4gFf0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAqAEIgogEv0MEAAAABAAAAAQAAAAEAAAAP1OIBf9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKQBCILIBP9DBAAAAAQAAAAEAAAABAAAAD9TiAZ/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACgAQiDCAa/QwQAAAAEAAAABAAAAAQAAAA/U4gFP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gH95AH95AH95AH95AH95AH95AH95AEiBSAF/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIgUgBf0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kASACIAYgByAIIAkgCiALIAz95AH95AH95AH95AH95AH95AH95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIgIgAv0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAilP0gASAALQAMIhxBD3H9DyAcQQR2/RcBIAP9DBAAAAAQAAAAEAAAABAAAAD9DQAEAAAAAAAAAAAAAAAAAABBAv1t/QwwMDAwMDAwMDAwMDAwMDAw/U79UCIC/RYAsv0TIAL9FgGy/SAB/eYB/eQB/eQBIAH9AALwByICIARBA/2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACsAf2JAf2pASIGQQT9rQH9UP36Af3mASAB/QAC4AciByAOQQP9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAqAH9iQH9qQEiCEEE/a0B/VD9+gH95gEgAf0AAtAHIgkgD0ED/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAKQB/YkB/akBIgpBBP2tAf1Q/foB/eYBIAH9AALAByILIBBBA/2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACgAf2JAf2pASIMQQT9rQH9UP36Af3mASAB/QACsAciBSARQQP9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAnAH9iQH9qQEiFUEE/a0B/VD9+gH95gEgAf0AAqAHIhYgEkED/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAJgB/YkB/akBIhdBBP2tAf1Q/foB/eYBIAH9AAKQByIYIBNBA/2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACUAf2JAf2pASIZQQT9rQH9UP36Af3mASAB/QACgAciGyAaQQP9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAkAH9iQH9qQEiFEEE/a0B/VD9+gH95gH95AH95AH95AH95AH95AH95AH95AEiDSAN/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIg0gDf0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kASACIAcgCSALIAUgFiAYIBv95AH95AH95AH95AH95AH95AH95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIgIgAv0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAilP0gASAALQAPIhxBD3H9DyAcQQR2/RcBIAP9DBAAAAAQAAAAEAAAABAAAAD9DQMHAAAAAAAAAAAAAAAAAABBAv1t/QwwMDAwMDAwMDAwMDAwMDAw/U79UCIC/RYAsv0TIAL9FgGy/SAB/eYBIAH9AALwBiICIARBAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAb9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALgBiIGIA5BAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAj9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALQBiIOIA9BAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAr9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALABiIPIBBBAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAz9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKwBiIQIBFBAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIBX9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKgBiIRIBJBAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIBf9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKQBiISIBNBAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIBn9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKABiITIBpBAv2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIBT9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYB/eQB/eQB/eQB/eQB/eQB/eQB/eQBIgQgBCAE/Q0EBQYHAAECAwwNDg8AAQID/eQBIgQgBCAE/Q0ICQoLAAECAwABAgMAAQID/eQBIAIgBiAOIA8gECARIBIgE/3kAf3kAf3kAf3kAf3kAf3kAf3kASIEIAQgBP0NBAUGBwABAgMMDQ4PAAECA/3kASIEIAQgBP0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAilP0gASAALQAOIgBBD3H9DyAAQQR2/RcBIAMgBP0NAgYAAAAAAAAAAAAAAAAAAEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9Tv1QIgP9FgCy/RMgA/0WAbL9IAH95gH95AH95AEiA/0fACAjlCAD/R8BkwuLKAMVewZ/AX0gAC0AASIbQQd2IRkgAC0AA0EIdCIcIAAtAAJyIRogG0EIdCIdIAAtAAByQf8HcSEYAn0CQCAbQQJ2QR9xIhtBH0cEQCAbDQEgGUEfdL4gGEUNAhogGLNDAACAM5QiHowgHiAdwUEASBsMAgsgGUEfdEGAgIACQQAgGBtyQYCAgPwHcr4MAQsgG0EXdCAZQR90ciAYQQ10ckGAgIDAA2q+CyAaQf8HcSEYIBpBgIACcUEPdiEZ/RMCfQJAIBpBCnZBH3EiGkEfRwRAIBoNASAZQR90viAYRQ0CGiAYs0MAAIAzlCIejCAeIBzBQQBIGwwCCyAZQR90QYCAgAJBACAYG3JBgICA/AdyvgwBCyAaQRd0IBlBH3RyIBhBDXRyQYCAgMADar4L/SABIAD9XAAs/YkB/akBIgRBBP2tASAB/VwAPP2HAf2nASID/bUBIAD9XAAo/YkB/akBIgVBBP2tASAB/VwAOP2HAf2nASIQ/bUBIAD9XAAk/YkB/akBIgxBBP2tASAB/VwANP2HAf2nASIG/bUBIAD9XAAg/YkB/akBIghBBP2tASAB/VwAMP2HAf2nASIJ/bUBIAD9XAAc/YkB/akBIgpBBP2tASAB/VwALP2HAf2nASIH/bUBIAD9XAAY/YkB/akBIgtBBP2tASAB/VwAKP2HAf2nASIN/bUBIAD9XAAU/YkB/akBIg5BBP2tASAB/VwAJP2HAf2nASIR/bUBIAD9XAAQ/YkB/akBIhJBBP2tASAB/VwAIP2HAf2nASIT/bUB/a4B/a4B/a4B/a4B/a4B/a4B/a4BIg8gDyAD/Q0ICQoLDA0ODwABAgMAAQID/a4BIg8gDyAD/Q0EBQYHAAECAwABAgMAAQID/a4BIBMgEf2uASAN/a4BIAf9rgEgCf2uASAG/a4BIBD9rgEgA/2uASIDIAMgA/0NCAkKCwwNDg8AAQIDAAECA/2uASIDIAMgA/0NBAUGBwABAgMAAQIDAAECA/2uAf0NAAECAxAREhMAAQIDAAECA/3HASAA/V0ABCIQIAP9DQEFAAAAAAAAAAAAAAAAAAAiA/0MPz8/Pz8/Pz8/Pz8/Pz8/P/1O/YkB/akB/ckB/dUBIAT9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAHP2HAf2nASIE/bUBIAX9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAGP2HAf2nASIF/bUBIAz9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAFP2HAf2nASIM/bUBIAj9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAEP2HAf2nASIG/bUBIAr9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwADP2HAf2nASII/bUBIAv9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwACP2HAf2nASIJ/bUBIA79DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwABP2HAf2nASIK/bUBIBL9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAAP2HAf2nASIH/bUB/a4B/a4B/a4B/a4B/a4B/a4B/a4BIgsgC/0MDwAAAA8AAAAPAAAADwAAAP0NCAkKCwwNDg8AAQIDAAECA/2uASILIAv9DA8AAAAPAAAADwAAAA8AAAD9DQQFBgcAAQIDAAECAwABAgP9rgEgByAK/a4BIAn9rgEgCP2uASAG/a4BIAz9rgEgBf2uASAE/a4BIgQgBP0MDwAAAA8AAAAPAAAADwAAAP0NCAkKCwwNDg8AAQIDAAECA/2uASIEIAT9DA8AAAAPAAAADwAAAA8AAAD9DQQFBgcAAQIDAAECAwABAgP9rgH9DQABAgMQERITAAECAwABAgP9xwEgEP0MDwAAAA8AAAAPAAAADwAAAP0NAAQAAAAAAAAAAAAAAAAAACIE/Qw/Pz8/Pz8/Pz8/Pz8/Pz8//U79iQH9qQH9yQH91QH9zgEgAP1cAEz9iQH9qQEiBf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABc/YcB/acBIgz9tQEgAP1cAEj9iQH9qQEiBv0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABY/YcB/acBIgj9tQEgAP1cAET9iQH9qQEiCf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABU/YcB/acBIgr9tQEgAP1cAED9iQH9qQEiB/0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABQ/YcB/acBIgv9tQEgAP1cADz9iQH9qQEiDf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABM/YcB/acBIg79tQEgAP1cADj9iQH9qQEiEf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABI/YcB/acBIhL9tQEgAP1cADT9iQH9qQEiE/0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABE/YcB/acBIg/9tQEgAP1cADD9iQH9qQEiFf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XABA/YcB/acBIhT9tQH9rgH9rgH9rgH9rgH9rgH9rgH9rgEiFiAW/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIhYgFv0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uASAUIA/9rgEgEv2uASAO/a4BIAv9rgEgCv2uASAI/a4BIAz9rgEiDCAM/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIgwgDP0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uAf0NAAECAxAREhMAAQIDAAECA/3HASAQ/QwPAAAADwAAAA8AAAAPAAAA/Q0CBgAAAAAAAAAAAAAAAAAAIgz9DD8/Pz8/Pz8/Pz8/Pz8/Pz/9Tv2JAf2pAf3JAf3VAf3OASAFQQT9rQEgAf1cAHz9hwH9pwEiBf21ASAGQQT9rQEgAf1cAHj9hwH9pwEiBv21ASAJQQT9rQEgAf1cAHT9hwH9pwEiCP21ASAHQQT9rQEgAf1cAHD9hwH9pwEiCf21ASANQQT9rQEgAf1cAGz9hwH9pwEiCv21ASARQQT9rQEgAf1cAGj9hwH9pwEiB/21ASATQQT9rQEgAf1cAGT9hwH9pwEiC/21ASAVQQT9rQEgAf1cAGD9hwH9pwEiDf21Af2uAf2uAf2uAf2uAf2uAf2uAf2uASIOIA79DA8AAAAPAAAADwAAAA8AAAD9DQgJCgsMDQ4PAAECAwABAgP9rgEiDiAO/QwPAAAADwAAAA8AAAAPAAAA/Q0EBQYHAAECAwABAgMAAQID/a4BIA0gC/2uASAH/a4BIAr9rgEgCf2uASAI/a4BIAb9rgEgBf2uASIFIAX9DA8AAAAPAAAADwAAAA8AAAD9DQgJCgsMDQ4PAAECAwABAgP9rgEiBSAF/QwPAAAADwAAAA8AAAAPAAAA/Q0EBQYHAAECAwABAgMAAQID/a4B/Q0AAQIDEBESEwABAgMAAQID/ccBIBD9DA8AAAAPAAAADwAAAA8AAAD9DQMHAAAAAAAAAAAAAAAAAAAiEP0MPz8/Pz8/Pz8/Pz8/Pz8/P/1O/YkB/akB/ckB/dUB/c4BIAD9XABs/YkB/akBIgX9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAnAH9hwH9pwEiBv21ASAA/VwAaP2JAf2pASII/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAJgB/YcB/acBIgn9tQEgAP1cAGT9iQH9qQEiCv0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XACUAf2HAf2nASIH/bUBIAD9XABg/YkB/akBIgv9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAkAH9hwH9pwEiDf21ASAA/VwAXP2JAf2pASIO/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAIwB/YcB/acBIhH9tQEgAP1cAFj9iQH9qQEiEv0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XACIAf2HAf2nASIT/bUBIAD9XABU/YkB/akBIg/9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAhAH9hwH9pwEiFf21ASAA/VwAUP2JAf2pASIU/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAIAB/YcB/acBIhb9tQH9rgH9rgH9rgH9rgH9rgH9rgH9rgEiFyAX/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIhcgF/0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uASAWIBX9rgEgE/2uASAR/a4BIA39rgEgB/2uASAJ/a4BIAb9rgEiBiAG/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIgYgBv0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uAf0NAAECAxAREhMAAQIDAAECA/3HASAALQAMIhhBD3H9DyAYQQR2/RcBIARBAv1t/QwwMDAwMDAwMDAwMDAwMDAw/U79UP2JAf2pAf3JAf3VAf3OASAFQQT9rQEgAf1cALwB/YcB/acBIgT9tQEgCEEE/a0BIAH9XAC4Af2HAf2nASIF/bUBIApBBP2tASAB/VwAtAH9hwH9pwEiBv21ASALQQT9rQEgAf1cALAB/YcB/acBIgj9tQEgDkEE/a0BIAH9XACsAf2HAf2nASIJ/bUBIBJBBP2tASAB/VwAqAH9hwH9pwEiCv21ASAPQQT9rQEgAf1cAKQB/YcB/acBIgf9tQEgFEEE/a0BIAH9XACgAf2HAf2nASIL/bUB/a4B/a4B/a4B/a4B/a4B/a4B/a4BIg0gDf0MDwAAAA8AAAAPAAAADwAAAP0NCAkKCwwNDg8AAQIDAAECA/2uASINIA39DA8AAAAPAAAADwAAAA8AAAD9DQQFBgcAAQIDAAECAwABAgP9rgEgCyAH/a4BIAr9rgEgCf2uASAI/a4BIAb9rgEgBf2uASAE/a4BIgQgBP0MDwAAAA8AAAAPAAAADwAAAP0NCAkKCwwNDg8AAQIDAAECA/2uASIEIAT9DA8AAAAPAAAADwAAAA8AAAD9DQQFBgcAAQIDAAECAwABAgP9rgH9DQABAgMQERITAAECAwABAgP9xwEgAC0ADSIYQQ9x/Q8gGEEEdv0XASADQQL9bf0MMDAwMDAwMDAwMDAwMDAwMP1O/VD9iQH9qQH9yQH91QH9zgEgAP1cAIwB/YkB/akBIgT9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwA3AH9hwH9pwEiBf21ASAA/VwAiAH9iQH9qQEiBv0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XADYAf2HAf2nASII/bUBIAD9XACEAf2JAf2pASIJ/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cANQB/YcB/acBIgr9tQEgAP1cAIAB/YkB/akBIgf9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwA0AH9hwH9pwEiC/21ASAA/VwAfP2JAf2pASIN/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAMwB/YcB/acBIg79tQEgAP1cAHj9iQH9qQEiEf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XADIAf2HAf2nASIS/bUBIAD9XAB0/YkB/akBIhP9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAxAH9hwH9pwEiD/21ASAA/VwAcP2JAf2pASIV/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAMAB/YcB/acBIgP9tQH9rgH9rgH9rgH9rgH9rgH9rgH9rgEiFCAUIAP9DQgJCgsMDQ4PAAECAwABAgP9rgEiFCAUIAP9DQQFBgcAAQIDAAECAwABAgP9rgEgAyAP/a4BIBL9rgEgDv2uASAL/a4BIAr9rgEgCP2uASAF/a4BIgMgAyAD/Q0ICQoLDA0ODwABAgMAAQID/a4BIgMgAyAD/Q0EBQYHAAECAwABAgMAAQID/a4B/Q0AAQIDEBESEwABAgMAAQID/ccBIAAtAA4iGEEPcf0PIBhBBHb9FwEgDEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9Tv1Q/YkB/akB/ckB/dUB/c4BIARBBP2tASAB/VwA/AH9hwH9pwEiA/21ASAGQQT9rQEgAf1cAPgB/YcB/acBIgT9tQEgCUEE/a0BIAH9XAD0Af2HAf2nASIF/bUBIAdBBP2tASAB/VwA8AH9hwH9pwEiDP21ASANQQT9rQEgAf1cAOwB/YcB/acBIgb9tQEgEUEE/a0BIAH9XADoAf2HAf2nASII/bUBIBNBBP2tASAB/VwA5AH9hwH9pwEiCf21ASAVQQT9rQEgAf1cAOAB/YcB/acBIgr9tQH9rgH9rgH9rgH9rgH9rgH9rgH9rgEiByAHIAP9DQgJCgsMDQ4PAAECAwABAgP9rgEiByAHIAP9DQQFBgcAAQIDAAECAwABAgP9rgEgCiAJ/a4BIAj9rgEgBv2uASAM/a4BIAX9rgEgBP2uASAD/a4BIgMgAyAD/Q0ICQoLDA0ODwABAgMAAQID/a4BIgMgAyAD/Q0EBQYHAAECAwABAgMAAQID/a4B/Q0AAQIDEBESEwABAgMAAQID/ccBIAAtAA8iAEEPcf0PIABBBHb9FwEgEEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9Tv1Q/YkB/akB/ckB/dUB/c4BIgP9HQC0/RMgA/0dAbT9IAH95gEiA/0fACAD/R8BkyAClAvxBAMLfwN7AX0CQCABIAJODQAgACgCCCELIAAoAgwiB0EATARAIAIgAWtBAnQiAEUNASALIAFBAnRqQQAgAPwLAA8LIAAoAgAgASAHbEESbGohCCAHQRJsIQwgACgCBCENA0BDAAAAACERQQAhCSAIIQADQCANIAlBB3RqIQQgAC0AASIFQRh0QYCAgIB4cSEDIAAtAAAgBUEIdHIiBkH/B3EhCiAGQf//A3EhBgJAAkAgBUECdkEfcSIFBEAgBUEfRw0BIAZBDXQgA3JBgICA/AdyIQMMAgsgCkUNASADQYCAgJgEciAKZyIDQRd0ayAGQQkgA0Efc2t0QQ50QYCA/wNxciEDDAELIAVBF3QgCkENdHIgA2pBgICAwANqIQMLIAT9AAAAIAD9AAACIg79DA8PDw8PDw8PDw8PDw8PDw/9Tv0M+Pj4+Pj4+Pj4+Pj4+Pj4+P1uIg/9hwEiEP2nAf36Af3mASAE/QAAECAQ/agB/foB/eYB/eQBIAT9AAAgIA/9iAEiD/2nAf36Af3mAf3kASAE/QAAMCAP/agB/foB/eYB/eQBIAT9AABAIA5BBP1t/Qz4+Pj4+Pj4+Pj4+Pj4+Pj4/W4iDv2HASIP/acB/foB/eYB/eQBIAT9AABQIA/9qAH9+gH95gH95AEgBP0AAGAgDv2IASIO/acB/foB/eYB/eQBIAT9AABwIA79qAH9+gH95gH95AEiDv0fACAO/R8BkiAO/R8CkiAO/R8DkiADvpQgEZIhESAAQRJqIQAgCUEBaiIJIAdHDQALIAsgAUECdGogETgCACAIIAxqIQggAUEBaiIBIAJHDQALCwuBAQEBfyMAQSBrIggkAAJAIAVBAEwNACAEQQBMBEAgBUECdCIARQ0BIAYgB0ECdGpBACAA/AsADAELIAggBTYCHCAIIARBBXY2AhggCCACIANqNgIMIAggBiAHQQJ0ajYCFCAIIAAgAUECdGo2AhBBAyAIQQxqIAUQAQsgCEEgaiQAC+YEAgx/A3sCQCABIAJODQAgAiABa0ECdCIDBEAgACgCCCABQQJ0akEAIAP8CwALIAAoAgwiCkEATA0AIAAoAgghCyAAKAIQIQwgACgCACENIAAoAgQhDgNAIA4gCEEHdGohAyANIAggDGwgAWpBEmxqIQUgASEAA0AgBS0AASIGQRh0QYCAgIB4cSEEIAUtAAAgBkEIdHIiCUH/B3EhByAJQf//A3EhCQJAAkAgBkECdkEfcSIGBEAgBkEfRw0BIAlBDXQgBHJBgICA/AdyIQQMAgsgB0UNASAEQYCAgJgEciAHZyIEQRd0ayAJQQkgBEEfc2t0QQ50QYCA/wNxciEEDAELIAZBF3QgB0ENdHIgBGpBgICAwANqIQQLIAsgAEECdGoiByAD/QAAACAF/QAAAiIP/QwPDw8PDw8PDw8PDw8PDw8P/U79DPj4+Pj4+Pj4+Pj4+Pj4+Pj9biIQ/YcBIhH9pwH9+gH95gEgA/0AABAgEf2oAf36Af3mAf3kASAD/QAAICAQ/YgBIhD9pwH9+gH95gH95AEgA/0AADAgEP2oAf36Af3mAf3kASAD/QAAQCAPQQT9bf0M+Pj4+Pj4+Pj4+Pj4+Pj4+P1uIg/9hwEiEP2nAf36Af3mAf3kASAD/QAAUCAQ/agB/foB/eYB/eQBIAP9AABgIA/9iAEiD/2nAf36Af3mAf3kASAD/QAAcCAP/agB/foB/eYB/eQBIg/9HwAgD/0fAZIgD/0fApIgD/0fA5IgBL6UIAcqAgCSOAIAIAVBEmohBSAAQQFqIgAgAkcNAAsgCEEBaiIIIApHDQALCwuBAQEBfyMAQSBrIggkAAJAIAVBAEwNACAEQQBMBEAgBUECdCIARQ0BIAYgB0ECdGpBACAA/AsADAELIAggBTYCHCAIIARBBXY2AhggCCACIANqNgIMIAggBiAHQQJ0ajYCFCAIIAAgAUECdGo2AhBBAiAIQQxqIAUQAQsgCEEgaiQAC4MMAw1/AX0EeyMAQYAQayIRJAACQCAJQQBMDQAgCkEATA0AIApBAnQhDSAIQQJ0IQ8gBiAHQQJ0aiEQIAlBAWtBA08EQCAJQfz///8HcSEWA0AgDUUiEkUEQCAQIAwgD2xqQQAgDfwLAAsgEkUEQCAQIA8gDEEBcmxqQQAgDfwLAAsgEkUEQCAQIA8gDEECcmxqQQAgDfwLAAsgEkUEQCAQIA8gDEEDcmxqQQAgDfwLAAsgDEEEaiEMIA5BBGoiDiAWRw0ACwsgCUEDcSIOBEADQCANBEAgECAMIA9sakEAIA38CwALIAxBAWohDCAVQQFqIhUgDkcNAAsLIAtBAEwNACAJQQFGBEAgCkH8////B3EhAiADIARqIQQgBiAHQQJ0aiEDIAAgAUECdGohBiAKQQRJIQdBACEAA0AgBCAAIAVsaiEBIAYgAEECdGoqAgAhGUEAIQwCQCAHRQRAIBn9EyEaA0AgAyAMQQJ0aiIIIBogASAMQQF0av1dAAAiG/0M/3//f/9//3//f/9//3//f/1O/akBQQ39qwEiHCAc/QwAAIAPAACADwAAgA8AAIAP/U4iHP0MAACADwAAgA8AAIAPAACAD/03/QwAAAA4AAAAOAAAADgAAAA4/U79rgEiHf0MAACAOAAAgDgAAIA4AACAOP2uAf0MAACAuAAAgLgAAIC4AACAuP3kASAd/QwAAAA4AAAAOAAAADgAAAA4/a4BIBz9DAAAAAAAAAAAAAAAAAAAAAD9N/1SIBv9pwH9DAAAAIAAAACAAAAAgAAAAID9Tv1Q/eYBIAj9AAIA/eQB/QsCACAMQQRqIgwgAkcNAAsgAiIMIApGDQELA0AgAyAMQQJ0aiIIIBkgASAMQQF0ai8AACIJQf//AXFBDXQiDUGAgIDAA0EAIA1BgICA/ABxIg1BgICA/ABGG2oiDkGAgIDAA2ogDkGAgIDEA2q+QwAAgLiSvCANGyAJQRB0QYCAgIB4cXK+lCAIKgIAkjgCACAMQQFqIgwgCkcNAAsLIABBAWoiACALRw0ACwwBCyADIARqIRAgBiAHQQJ0aiESIAAgAUECdGohFSAKIQFBACEAA0AgACAKSARAIBIgAEECdGohFiAQIABBAXRqIRhBgARBASABIAFBAUwbIgMgA0GABE4bIgdB/AdxIQMgB0H8B3EhBkEAIQQgAUEESCENA0AgGCAEIAVsaiEOQQAhDAJAIA1FBEADQCARIAxBAnRqIA4gDEEBdGr9XQAAIhr9DP9//3//f/9//3//f/9//3/9Tv2pAUEN/asBIhsgG/0MAACADwAAgA8AAIAPAACAD/1OIhv9DAAAgA8AAIAPAACADwAAgA/9N/0MAAAAOAAAADgAAAA4AAAAOP1O/a4BIhz9DAAAgDgAAIA4AACAOAAAgDj9rgH9DAAAgLgAAIC4AACAuAAAgLj95AEgHP0MAAAAOAAAADgAAAA4AAAAOP2uASAb/QwAAAAAAAAAAAAAAAAAAAAA/Tf9UiAa/acB/QwAAACAAAAAgAAAAIAAAACA/U79UP0LBAAgDEEEaiIMIAZHDQALIAYiDCAHRg0BCwNAIBEgDEECdGogDiAMQQF0ai8AACIPQf//AXFBDXQiE0GAgIDAA0EAIBNBgICA/ABxIhNBgICA/ABGG2oiFEGAgIDAA2ogFEGAgIDEA2q+QwAAgLiSvCATGyAPQRB0QYCAgIB4cXI2AgAgDEEBaiIMIAdHDQALCyAVIARBAnRqIRNBACEOA0AgFiAIIA5sQQJ0aiEPIBMgAiAObEECdGoqAgAhGUEAIQwCQCANRQRAIBn9EyEaA0AgDyAMQQJ0IhRqIhcgF/0AAgAgESAUav0ABAAgGv3mAf3kAf0LAgAgDEEEaiIMIANHDQALIAMiDCAHRg0BCwNAIA8gDEECdCIUaiIXIBcqAgAgESAUaioCACAZlJI4AgAgDEEBaiIMIAdHDQALCyAOQQFqIg4gCUcNAAsgBEEBaiIEIAtHDQALCyABQYAEayEBIABBgARqIgAgCkgNAAsLIBFBgBBqJAALBQEIfwALvQcDDX8BfQF7IwBBgBBrIhIkAAJAIAlBAEwNACAKQQBMDQAgCkECdCEOIAhBAnQhECAGIAdBAnRqIREgCUEBa0EDTwRAIAlB/P///wdxIRQDQCAORSITRQRAIBEgDCAQbGpBACAO/AsACyATRQRAIBEgECAMQQFybGpBACAO/AsACyATRQRAIBEgECAMQQJybGpBACAO/AsACyATRQRAIBEgECAMQQNybGpBACAO/AsACyAMQQRqIQwgD0EEaiIPIBRHDQALCyAJQQNxIg8EQANAIA4EQCARIAwgEGxqQQAgDvwLAAsgDEEBaiEMIA1BAWoiDSAPRw0ACwsgC0EATA0AIAlBAUYEQCAKQfz///8HcSECIAMgBGohBCAGIAdBAnRqIQMgACABQQJ0aiEBQQAhDSAKQQRJIQYDQCAEIAUgDWxqIQAgASANQQJ0aioCACEZQQAhDAJAIAZFBEAgGf0TIRoDQCADIAxBAnRqIgcgGiAAIAxBAXRq/QQAAEEQ/asB/eYBIAf9AAIA/eQB/QsCACAMQQRqIgwgAkcNAAsgAiIMIApGDQELA0AgAyAMQQJ0aiIHIBkgACAMQQF0ai8AAEEQdL6UIAcqAgCSOAIAIAxBAWoiDCAKRw0ACwsgDUEBaiINIAtHDQALDAELIAMgBGohECAGIAdBAnRqIREgACABQQJ0aiETQQAhACAKIQEDQCAAIApIBEAgESAAQQJ0aiEUIBAgAEEBdGohF0GABEEBIAEgAUEBTBsiAyADQYAEThsiB0H8B3EhAyAHQfwHcSEGQQAhBCABQQRIIQ4DQCAXIAQgBWxqIQ1BACEMAkAgDkUEQANAIBIgDEECdGogDSAMQQF0av0EAABBEP2rAf0LBAAgDEEEaiIMIAZHDQALIAYiDCAHRg0BCwNAIBIgDEECdGogDSAMQQF0ai8AAEEQdDYCACAMQQFqIgwgB0cNAAsLIBMgBEECdGohGEEAIQ8DQCAUIAggD2xBAnRqIQ0gGCACIA9sQQJ0aioCACEZQQAhDAJAIA5FBEAgGf0TIRoDQCANIAxBAnQiFWoiFiAW/QACACASIBVq/QAEACAa/eYB/eQB/QsCACAMQQRqIgwgA0cNAAsgAyIMIAdGDQELA0AgDSAMQQJ0IhVqIhYgFioCACASIBVqKgIAIBmUkjgCACAMQQFqIgwgB0cNAAsLIA9BAWoiDyAJRw0ACyAEQQFqIgQgC0cNAAsLIAFBgARrIQEgAEGABGoiACAKSA0ACwsgEkGAEGokAAvOAQIGfwF9IwBBgAJrIgUkAAJAIAEgAk4NACAAKAIQIgZBAEoEQCAAKAIAIAEgBmxB0gFsaiEEIAAoAgghByAAKAIEIQgDQEMAAAAAIQlBACEDA0AgBCAIIANBCHRqIAcgA0ECdGoqAgAgBRAIIAmSIQkgBEHSAWohBCADQQFqIgMgBkcNAAsgACgCDCABQQJ0aiAJOAIAIAFBAWoiASACRw0ACwwBCyACIAFrQQJ0IgJFDQAgACgCDCABQQJ0akEAIAL8CwALIAVBgAJqJAALFgAgACABIAIgAyAEIAUgBiAHQQ8QBQvfAQILfwJ9IwBBgAJrIgYkAAJAIAEgAk4NACACIAFrQQJ0IgMEQCAAKAIMIAFBAnRqQQAgA/wLAAsgACgCECIHQQBMDQAgACgCFCEIIAAoAgAhCSAAKAIIIQogACgCBCELA0AgCyAEQQh0aiEMIAkgBCAIbCABakHSAWxqIQUgCiAEQQJ0aioCACEOIAEhAwNAIAUgDCAOIAYQCCEPIAAoAgwgA0ECdGoiDSAPIA0qAgCSOAIAIAVB0gFqIQUgA0EBaiIDIAJHDQALIARBAWoiBCAHRw0ACwsgBkGAAmokAAsWACAAIAEgAiADIAQgBSAGIAdBDhAFC6gBAgR/AX0CQCABIAJODQAgACgCDCIFQQBKBEAgACgCACABIAVsQbABbGohAyAAKAIEIQYDQEMAAAAAIQdBACEEA0AgAyAGIARBCnRqEAkgB5IhByADQbABaiEDIARBAWoiBCAFRw0ACyAAKAIIIAFBAnRqIAc4AgAgAUEBaiIBIAJHDQALDAELIAIgAWtBAnQiAkUNACAAKAIIIAFBAnRqQQAgAvwLAAsLZQEBfyMAQSBrIggkAAJAIARBAEwNACAFQQBMDQAgCCAFNgIcIAggBEEIdjYCGCAIIAIgA2o2AgwgCCAGIAdBAnRqNgIUIAggACABQQJ0ajYCEEENIAhBDGogBRABCyAIQSBqJAALrwEBCX8CQCABIAJODQAgAiABa0ECdCIDBEAgACgCCCABQQJ0akEAIAP8CwALIAAoAgwiBkEATA0AIAAoAhAhByAAKAIAIQggACgCBCEJA0AgCSAEQQp0aiEKIAggBCAHbCABakGwAWxqIQUgASEDA0AgACgCCCADQQJ0aiILIAsqAgAgBSAKEAmSOAIAIAVBsAFqIQUgA0EBaiIDIAJHDQALIARBAWoiBCAGRw0ACwsLuAYDEn8BewF9AkAgACgCDCIKQQBMDQAgASACTg0AIAAoAhAhCyAAKAIIIQwgACgCACENIAAoAgQhDiAAKAIUIgNBBE4EQCADQfz///8HcSEFIANBBGsiD0EEcSERIA9BAnZBAWpB/v///wdxIRIDQCAMIAYgC2xBAnRqIRMgDSADIAZsQQJ0aiEHIAEhBANAIA4gAyAEbEECdGohCUEEIQD9DAAAAAAAAAAAAAAAAAAAAAAhFUEAIQhBACEQIA9BBE8EQANAIAkgAEECdCIUav0AAAAgByAUav0AAAD95gEgCSAIQQJ0Ighq/QAAACAHIAhq/QAAAP3mASAV/eQB/eQBIRUgAEEEaiEIIABBCGohACAQQQJqIhAgEkcNAAsLIBFFBEAgCSAIQQJ0IgBq/QAAACAAIAdq/QAAAP3mASAV/eQBIRULIBX9HwAgFf0fAZIgFf0fApIgFf0fA5IhFiADIAUiAEoEQANAIAkgAEECdCIIaioCACAHIAhqKgIAlCAWkiEWIABBAWoiACADRw0ACwsgEyAEQQJ0aiAWOAIAIARBAWoiBCACRw0ACyAGQQFqIgYgCkcNAAsMAQsgA0EASgRAIANBAUYhBwNAIAwgBCALbEECdGohCSANIAMgBGxBAnRqIQUgASEAA0AgCSAAQQJ0agJ9IA4gACADbEECdGoiBioCACAFKgIAlCIWIAcNABogBioCBCAFKgIElCAWkiIWIANBAkYNABogBioCCCAFKgIIlCAWkgs4AgAgAEEBaiIAIAJHDQALIARBAWoiBCAKRw0ACwwBCyALQQJ0IQUgDCABQQJ0aiEDIAIgAWtBAnQhAUEAIQAgCkEETwRAIApB/P///wdxIQcDQCABRSICRQRAIAMgACAFbGpBACAB/AsACyACRQRAIAMgBSAAQQFybGpBACAB/AsACyACRQRAIAMgBSAAQQJybGpBACAB/AsACyACRQRAIAMgBSAAQQNybGpBACAB/AsACyAAQQRqIQAgBkEEaiIGIAdHDQALCyAKQQNxIgJFDQADQCABBEAgAyAAIAVsakEAIAH8CwALIABBAWohACAEQQFqIgQgAkcNAAsLC2UBAX8jAEEgayIIJAACQCAEQQBMDQAgBUEATA0AIAggBTYCHCAIIARBCHY2AhggCCACIANqNgIMIAggBiAHQQJ0ajYCFCAIIAAgAUECdGo2AhBBDCAIQQxqIAUQAQsgCEEgaiQAC7oBAgV/AX0CQCABIAJODQAgACgCECIFQQBKBEAgACgCACABIAVsQZABbGohBCAAKAIIIQYgACgCBCEHA0BDAAAAACEIQQAhAwNAIAQgByADQQh0aiAGIANBAnRqKgIAEAogCJIhCCAEQZABaiEEIANBAWoiAyAFRw0ACyAAKAIMIAFBAnRqIAg4AgAgAUEBaiIBIAJHDQALDAELIAIgAWtBAnQiAkUNACAAKAIMIAFBAnRqQQAgAvwLAAsLFgAgACABIAIgAyAEIAUgBiAHQQsQBQvLAQIKfwJ9AkAgASACTg0AIAIgAWtBAnQiAwRAIAAoAgwgAUECdGpBACAD/AsACyAAKAIQIgZBAEwNACAAKAIUIQcgACgCACEIIAAoAgghCSAAKAIEIQoDQCAKIARBCHRqIQsgCCAEIAdsIAFqQZABbGohBSAJIARBAnRqKgIAIQ0gASEDA0AgBSALIA0QCiEOIAAoAgwgA0ECdGoiDCAOIAwqAgCSOAIAIAVBkAFqIQUgA0EBaiIDIAJHDQALIARBAWoiBCAGRw0ACwsLFgAgACABIAIgAyAEIAUgBiAHQQoQBQuzBAMCewt/AX0CQCABIAJODQAgACgCCCENIAAoAgwiCUEATARAIAIgAWtBAnQiAEUNASANIAFBAnRqQQAgAPwLAA8LIAAoAgAgASAJbEEibGohCiAJQSJsIQ4gACgCBCEPA0BDAAAAACEQQQAhCyAKIQADQCAPIAtBB3RqIQYgAC0AASIHQRh0QYCAgIB4cSEFIAAtAAAgB0EIdHIiCEH/B3EhDCAIQf//A3EhCAJAAkAgB0ECdkEfcSIHBEAgB0EfRw0BIAhBDXQgBXJBgICA/AdyIQUMAgsgDEUNASAFQYCAgJgEciAMZyIFQRd0ayAIQQkgBUEfc2t0QQ50QYCA/wNxciEFDAELIAdBF3QgDEENdHIgBWpBgICAwANqIQULIAb9AAAAIAD9AAACIgP9hwEiBP2nAf36Af3mASAG/QAAECAE/agB/foB/eYB/eQBIAb9AAAgIAP9iAEiA/2nAf36Af3mAf3kASAG/QAAMCAD/agB/foB/eYB/eQBIAb9AABAIAD9AAASIgP9hwEiBP2nAf36Af3mAf3kASAG/QAAUCAE/agB/foB/eYB/eQBIAb9AABgIAP9iAEiA/2nAf36Af3mAf3kASAG/QAAcCAD/agB/foB/eYB/eQBIgP9HwAgA/0fAZIgA/0fApIgA/0fA5IgBb6UIBCSIRAgAEEiaiEAIAtBAWoiCyAJRw0ACyANIAFBAnRqIBA4AgAgCiAOaiEKIAFBAWoiASACRw0ACwsLgQEBAX8jAEEgayIIJAACQCAFQQBMDQAgBEEATARAIAVBAnQiAEUNASAGIAdBAnRqQQAgAPwLAAwBCyAIIAU2AhwgCCAEQQV2NgIYIAggAiADajYCDCAIIAYgB0ECdGo2AhQgCCAAIAFBAnRqNgIQQQkgCEEMaiAFEAELIAhBIGokAAuoBAICewx/AkAgASACTg0AIAIgAWtBAnQiBQRAIAAoAgggAUECdGpBACAF/AsACyAAKAIMIgxBAEwNACAAKAIIIQ0gACgCECEOIAAoAgAhDyAAKAIEIRADQCAQIApBB3RqIQUgDyAKIA5sIAFqQSJsaiEHIAEhAANAIActAAEiCEEYdEGAgICAeHEhBiAHLQAAIAhBCHRyIgtB/wdxIQkgC0H//wNxIQsCQAJAIAhBAnZBH3EiCARAIAhBH0cNASALQQ10IAZyQYCAgPwHciEGDAILIAlFDQEgBkGAgICYBHIgCWciBkEXdGsgC0EJIAZBH3NrdEEOdEGAgP8DcXIhBgwBCyAIQRd0IAlBDXRyIAZqQYCAgMADaiEGCyANIABBAnRqIgkgBf0AAAAgB/0AAAIiA/2HASIE/acB/foB/eYBIAX9AAAQIAT9qAH9+gH95gH95AEgBf0AACAgA/2IASID/acB/foB/eYB/eQBIAX9AAAwIAP9qAH9+gH95gH95AEgBf0AAEAgB/0AABIiA/2HASIE/acB/foB/eYB/eQBIAX9AABQIAT9qAH9+gH95gH95AEgBf0AAGAgA/2IASID/acB/foB/eYB/eQBIAX9AABwIAP9qAH9+gH95gH95AEiA/0fACAD/R8BkiAD/R8CkiAD/R8DkiAGvpQgCSoCAJI4AgAgB0EiaiEHIABBAWoiACACRw0ACyAKQQFqIgogDEcNAAsLC5sBAQF/IwBBIGsiCSQAAkAgBkEATA0AIAdBAEwNACAIQQBMBEAgBiAHbCIAQQBMDQEgAEECdCIARQ0BIAQgBUECdGpBACAA/AsADAELIAkgCDYCHCAJIAc2AhggCSAGNgIUIAkgBCAFQQJ0ajYCECAJIAIgA0ECdGo2AgwgCSAAIAFBAnRqNgIIQQEgCUEIaiAHEAELIAlBIGokAAuBAQEBfyMAQSBrIggkAAJAIAVBAEwNACAEQQBMBEAgBUECdCIARQ0BIAYgB0ECdGpBACAA/AsADAELIAggBTYCHCAIIARBBXY2AhggCCACIANqNgIMIAggBiAHQQJ0ajYCFCAIIAAgAUECdGo2AhBBCCAIQQxqIAUQAQsgCEEgaiQAC7YJAw5/BXsCfQJAIAEgAk4NACAAKAIIIQwgACgCECIKQQBMBEAgAiABa0ECdCIARQ0BIAwgAUECdGpBACAA/AsADwsgACgCACABIApsQRhsaiELIApBGGwhDSAAKAIMIQ4gACgCBCEPA0BDAAAAACEWQQAhCCALIQADQCAALQABIgRBGHRBgICAgHhxIQcgAC0AA0EIdCIJIAAtAAJyIQMgAC0AACAEQQh0ciIGQf8HcSEFIAZB//8DcSEGIA4gCEECdGoCQAJAIARBAnZBH3EiBARAIARBH0cNASAGQQ10IAdyQYCAgPwHciEHDAILIAVFDQEgB0GAgICYBHIgBWciBUEXdGsgBkEJIAVBH3NrdEEOdEGAgP8DcXIhBwwBCyAEQRd0IAVBDXRyIAdqQYCAgMADaiEHCyAPIAhBB3RqIQUqAgAgA0H/B3EhBiAJQRB0QYCAgIB4cSEEAkACQCADQQp2QR9xIgkEQCAJQR9HDQEgA0ENdCAEckGAgID8B3IhBAwCCyAGRQ0BIARBgICAmARyIAZnIgRBF3RrIANBCSAEQR9za3RBDnRBgID/A3FyIQQMAQsgCUEXdCAGQQ10ciAEakGAgIDAA2ohBAsgBL6UIBaSIAX9AAIwIAD9XAAU/YkB/akBIhH9DA8AAAAPAAAADwAAAA8AAAD9TiAAKAAEIgNBCHb9ESADQQl2/RwBIANBCnb9HAIgA0ELdv0cAyIS/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAF/QACICAA/VwAEP2JAf2pASIU/QwPAAAADwAAAA8AAAAPAAAA/U4gEkEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAF/QACECAA/VwADP2JAf2pASIS/QwPAAAADwAAAA8AAAAPAAAA/U4gA/0RIANBAXb9HAEgA0ECdv0cAiADQQN2/RwDIhP9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAX9AAIAIAD9XAAI/YkB/akBIhX9DA8AAAAPAAAADwAAAA8AAAD9TiATQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAX9AAJAIANBEHb9ESADQRF2/RwBIANBEnb9HAIgA0ETdv0cAyITQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAVQQT9rQH9UP36Af3mAf3kAf3kASAF/QACUCAT/QwQAAAAEAAAABAAAAAQAAAA/U4gEkEE/a0B/VD9+gH95gH95AH95AEgBf0AAmAgA0EYdv0RIANBGXb9HAEgA0Eadv0cAiADQRt2/RwDIhJBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBRBBP2tAf1Q/foB/eYB/eQB/eQBIAX9AAJwIBL9DBAAAAAQAAAAEAAAABAAAAD9TiARQQT9rQH9UP36Af3mAf3kASIRIBEgEf0NBAUGBwABAgMMDQ4PAAECA/3kASIRIBEgEf0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAHvpSSIRYgAEEYaiEAIAhBAWoiCCAKRw0ACyAMIAFBAnRqIBY4AgAgCyANaiELIAFBAWoiASACRw0ACwsLFgAgACABIAIgAyAEIAUgBiAHQQcQBguvCQIQfwV7AkAgASACTg0AIAIgAWtBAnQiCQRAIAAoAgggAUECdGpBACAJ/AsACyAAKAIQIgtBAEwNACAAKAIIIQwgACgCDCENIAAoAhQhDiAAKAIAIQ8gACgCBCEQA0AgDSAKQQJ0aiERIBAgCkEHdGohByAPIAogDmwgAWpBGGxqIQQgASEJA0AgBC0AASIFQRh0QYCAgIB4cSEGIAQtAANBCHQiEiAELQACciEAIAQtAAAgBUEIdHIiCEH/B3EhAyAIQf//A3EhCAJAAkAgBUECdkEfcSIFBEAgBUEfRw0BIAhBDXQgBnJBgICA/AdyIQYMAgsgA0UNASAGQYCAgJgEciADZyIGQRd0ayAIQQkgBkEfc2t0QQ50QYCA/wNxciEGDAELIAVBF3QgA0ENdHIgBmpBgICAwANqIQYLIABB/wdxIQUgEkEQdEGAgICAeHEhAwJAAkAgAEEKdkEfcSIIBEAgCEEfRw0BIABBDXQgA3JBgICA/AdyIQMMAgsgBUUNASADQYCAgJgEciAFZyIDQRd0ayAAQQkgA0Efc2t0QQ50QYCA/wNxciEDDAELIAhBF3QgBUENdHIgA2pBgICAwANqIQMLIAwgCUECdGoiBSAH/QACMCAE/VwAFP2JAf2pASIT/QwPAAAADwAAAA8AAAAPAAAA/U4gBCgABCIAQQh2/REgAEEJdv0cASAAQQp2/RwCIABBC3b9HAMiFP0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgB/0AAiAgBP1cABD9iQH9qQEiFv0MDwAAAA8AAAAPAAAADwAAAP1OIBRBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgB/0AAhAgBP1cAAz9iQH9qQEiFP0MDwAAAA8AAAAPAAAADwAAAP1OIAD9ESAAQQF2/RwBIABBAnb9HAIgAEEDdv0cAyIV/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAH/QACACAE/VwACP2JAf2pASIX/QwPAAAADwAAAA8AAAAPAAAA/U4gFUEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAH/QACQCAAQRB2/REgAEERdv0cASAAQRJ2/RwCIABBE3b9HAMiFUEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gF0EE/a0B/VD9+gH95gH95AH95AEgB/0AAlAgFf0MEAAAABAAAAAQAAAAEAAAAP1OIBRBBP2tAf1Q/foB/eYB/eQB/eQBIAf9AAJgIABBGHb9ESAAQRl2/RwBIABBGnb9HAIgAEEbdv0cAyIUQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAWQQT9rQH9UP36Af3mAf3kAf3kASAH/QACcCAU/QwQAAAAEAAAABAAAAAQAAAA/U4gE0EE/a0B/VD9+gH95gH95AEiEyATIBP9DQQFBgcAAQIDDA0ODwABAgP95AEiEyATIBP9DQgJCgsAAQIDAAECAwABAgP95AH9HwAgBr6UIBEqAgAgA76UkiAFKgIAkjgCACAEQRhqIQQgCUEBaiIJIAJHDQALIApBAWoiCiALRw0ACwsLFgAgACABIAIgAyAEIAUgBiAHQQYQBgugCAMMfwV7An0CQCABIAJODQAgACgCCCELIAAoAhAiCUEATARAIAIgAWtBAnQiAEUNASALIAFBAnRqQQAgAPwLAA8LIAAoAgAgASAJbEEWbGohCiAJQRZsIQwgACgCDCENIAAoAgQhDgNAQwAAAAAhFEEAIQcgCiEAA0AgDiAHQQd0aiEEIAAtAAEiBkEYdEGAgICAeHEhBSAALQAAIAZBCHRyIghB/wdxIQMgCEH//wNxIQggDSAHQQJ0aioCACEVAkACQCAGQQJ2QR9xIgYEQCAGQR9HDQEgCEENdCAFckGAgID8B3IhBQwCCyADRQ0BIAVBgICAmARyIANnIgNBF3RrIAhBCSADQR9za3RBDnRBgID/A3FyIQUMAQsgBkEXdCADQQ10ciAFakGAgIDAA2ohBQsgBP0AAjAgAP1cABL9iQH9qQEiD/0MDwAAAA8AAAAPAAAADwAAAP1OIAAoAAIiA0EIdv0RIANBCXb9HAEgA0EKdv0cAiADQQt2/RwDIhD9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAT9AAIgIAD9XAAO/YkB/akBIhL9DA8AAAAPAAAADwAAAA8AAAD9TiAQQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAT9AAIQIAD9XAAK/YkB/akBIhD9DA8AAAAPAAAADwAAAA8AAAD9TiAD/REgA0EBdv0cASADQQJ2/RwCIANBA3b9HAMiEf0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBP0AAgAgAP1cAAb9iQH9qQEiE/0MDwAAAA8AAAAPAAAADwAAAP1OIBFBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBP0AAkAgA0EQdv0RIANBEXb9HAEgA0ESdv0cAiADQRN2/RwDIhFBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBNBBP2tAf1Q/foB/eYB/eQB/eQBIAT9AAJQIBH9DBAAAAAQAAAAEAAAABAAAAD9TiAQQQT9rQH9UP36Af3mAf3kAf3kASAE/QACYCADQRh2/REgA0EZdv0cASADQRp2/RwCIANBG3b9HAMiEEEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gEkEE/a0B/VD9+gH95gH95AH95AEgBP0AAnAgEP0MEAAAABAAAAAQAAAAEAAAAP1OIA9BBP2tAf1Q/foB/eYB/eQBIg8gDyAP/Q0EBQYHAAECAwwNDg8AAQID/eQBIg8gDyAP/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AIBVDAACAwZSSIAW+lCAUkiEUIABBFmohACAHQQFqIgcgCUcNAAsgCyABQQJ0aiAUOAIAIAogDGohCiABQQFqIgEgAkcNAAsLCxYAIAAgASACIAMgBCAFIAYgB0EFEAYLlQgCDn8FewJAIAEgAk4NACACIAFrQQJ0IgMEQCAAKAIIIAFBAnRqQQAgA/wLAAsgACgCECIKQQBMDQAgACgCCCELIAAoAgwhDCAAKAIUIQ0gACgCACEOIAAoAgQhDwNAIAwgB0ECdGohECAPIAdBB3RqIQUgDiAHIA1sIAFqQRZsaiEEIAEhAANAIAQtAAEiCEEYdEGAgICAeHEhBiAELQAAIAhBCHRyIglB/wdxIQMgCUH//wNxIQkCQAJAIAhBAnZBH3EiCARAIAhBH0cNASAJQQ10IAZyQYCAgPwHciEGDAILIANFDQEgBkGAgICYBHIgA2ciA0EXdGsgCUEJIANBH3NrdEEOdEGAgP8DcXIhBgwBCyAIQRd0IANBDXRyIAZqQYCAgMADaiEGCyALIABBAnRqIgMgAyoCACAF/QACMCAE/VwAEv2JAf2pASIR/QwPAAAADwAAAA8AAAAPAAAA/U4gBCgAAiIDQQh2/REgA0EJdv0cASADQQp2/RwCIANBC3b9HAMiEv0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBf0AAiAgBP1cAA79iQH9qQEiFP0MDwAAAA8AAAAPAAAADwAAAP1OIBJBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBf0AAhAgBP1cAAr9iQH9qQEiEv0MDwAAAA8AAAAPAAAADwAAAP1OIAP9ESADQQF2/RwBIANBAnb9HAIgA0EDdv0cAyIT/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAF/QACACAE/VwABv2JAf2pASIV/QwPAAAADwAAAA8AAAAPAAAA/U4gE0EE/asB/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAF/QACQCADQRB2/REgA0ERdv0cASADQRJ2/RwCIANBE3b9HAMiE0EE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gFUEE/a0B/VD9+gH95gH95AH95AEgBf0AAlAgE/0MEAAAABAAAAAQAAAAEAAAAP1OIBJBBP2tAf1Q/foB/eYB/eQB/eQBIAX9AAJgIANBGHb9ESADQRl2/RwBIANBGnb9HAIgA0Ebdv0cAyISQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAUQQT9rQH9UP36Af3mAf3kAf3kASAF/QACcCAS/QwQAAAAEAAAABAAAAAQAAAA/U4gEUEE/a0B/VD9+gH95gH95AEiESARIBH9DQQFBgcAAQIDDA0ODwABAgP95AEiESARIBH9DQgJCgsAAQIDAAECAwABAgP95AH9HwAgECoCAEMAAIDBlJIgBr6UkjgCACAEQRZqIQQgAEEBaiIAIAJHDQALIAdBAWoiByAKRw0ACwsLFgAgACABIAIgAyAEIAUgBiAHQQQQBguDBAMIfwF9AXsCQCAJQQBMDQAgCkEATA0AIApBAnQhDyAIQQJ0IQ0gBiAHQQJ0aiEOIAlBAWtBA08EQCAJQfz///8HcSERA0AgD0UiEkUEQCAOIAwgDWxqQQAgD/wLAAsgEkUEQCAOIA0gDEEBcmxqQQAgD/wLAAsgEkUEQCAOIA0gDEECcmxqQQAgD/wLAAsgEkUEQCAOIA0gDEEDcmxqQQAgD/wLAAsgDEEEaiEMIBBBBGoiECARRw0ACwsgCUEDcSIRBEADQCAPBEAgDiAMIA1sakEAIA/8CwALIAxBAWohDCATQQFqIhMgEUcNAAsLIAtBAEwNACAKQfz///8HcSERIAMgBEECdGohEiAGIAdBAnRqIRMgACABQQJ0aiEHQQAhBiAKQQRJIQQDQCATIAYgCGxBAnRqIQ0gByACIAZsQQJ0aiEDQQAhEANAIBIgBSAQbEECdGohDiADIBBBAnRqKgIAIRRBACEMAkAgBEUEQCAU/RMhFQNAIA0gDEECdCIBaiIAIAD9AAIAIAEgDmr9AAIAIBX95gH95AH9CwIAIAxBBGoiDCARRw0ACyARIgwgCkYNAQsDQCANIAxBAnQiAWoiACAAKgIAIAEgDmoqAgAgFJSSOAIAIAxBAWoiDCAKRw0ACwsgEEEBaiIQIAtHDQALIAZBAWoiBiAJRw0ACwsLAgALCwoBAEGACAsDoAYB" - const val MT_MJS: String = "YXN5bmMgZnVuY3Rpb24gY3JlYXRlU2thaW5ldEtlcm5lbHMobW9kdWxlQXJnPXt9KXt2YXIgbW9kdWxlUnRuO3ZhciBNb2R1bGU9bW9kdWxlQXJnO3ZhciBFTlZJUk9OTUVOVF9JU19XRUI9dHlwZW9mIHdpbmRvdz09Im9iamVjdCI7dmFyIEVOVklST05NRU5UX0lTX1dPUktFUj10eXBlb2YgV29ya2VyR2xvYmFsU2NvcGUhPSJ1bmRlZmluZWQiO3ZhciBFTlZJUk9OTUVOVF9JU19OT0RFPXR5cGVvZiBwcm9jZXNzPT0ib2JqZWN0IiYmcHJvY2Vzcy52ZXJzaW9ucz8ubm9kZSYmcHJvY2Vzcy50eXBlIT0icmVuZGVyZXIiO3ZhciBFTlZJUk9OTUVOVF9JU19QVEhSRUFEPUVOVklST05NRU5UX0lTX1dPUktFUiYmc2VsZi5uYW1lPy5zdGFydHNXaXRoKCJlbS1wdGhyZWFkIik7aWYoRU5WSVJPTk1FTlRfSVNfTk9ERSl7Y29uc3R7Y3JlYXRlUmVxdWlyZX09YXdhaXQgaW1wb3J0KCJtb2R1bGUiKTt2YXIgcmVxdWlyZT1jcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybC5zdGFydHNXaXRoKCJmaWxlOiIpP2ltcG9ydC5tZXRhLnVybDpwcm9jZXNzLmN3ZCgpKyIvIik7dmFyIHdvcmtlcl90aHJlYWRzPXJlcXVpcmUoIndvcmtlcl90aHJlYWRzIik7Z2xvYmFsLldvcmtlcj13b3JrZXJfdGhyZWFkcy5Xb3JrZXI7RU5WSVJPTk1FTlRfSVNfV09SS0VSPSF3b3JrZXJfdGhyZWFkcy5pc01haW5UaHJlYWQ7RU5WSVJPTk1FTlRfSVNfUFRIUkVBRD1FTlZJUk9OTUVOVF9JU19XT1JLRVImJndvcmtlcl90aHJlYWRzWyJ3b3JrZXJEYXRhIl09PSJlbS1wdGhyZWFkIn12YXIgYXJndW1lbnRzXz1bXTt2YXIgdGhpc1Byb2dyYW09Ii4vdGhpcy5wcm9ncmFtIjt2YXIgcXVpdF89KHN0YXR1cyx0b1Rocm93KT0+e3Rocm93IHRvVGhyb3d9O3ZhciBfc2NyaXB0TmFtZT1pbXBvcnQubWV0YS51cmw7dmFyIHNjcmlwdERpcmVjdG9yeT0iIjtmdW5jdGlvbiBsb2NhdGVGaWxlKHBhdGgpe2lmKE1vZHVsZVsibG9jYXRlRmlsZSJdKXtyZXR1cm4gTW9kdWxlWyJsb2NhdGVGaWxlIl0ocGF0aCxzY3JpcHREaXJlY3RvcnkpfXJldHVybiBzY3JpcHREaXJlY3RvcnkrcGF0aH12YXIgcmVhZEFzeW5jLHJlYWRCaW5hcnk7aWYoRU5WSVJPTk1FTlRfSVNfTk9ERSl7dmFyIGZzPXJlcXVpcmUoImZzIik7aWYoX3NjcmlwdE5hbWUuc3RhcnRzV2l0aCgiZmlsZToiKSl7c2NyaXB0RGlyZWN0b3J5PXJlcXVpcmUoInBhdGgiKS5kaXJuYW1lKHJlcXVpcmUoInVybCIpLmZpbGVVUkxUb1BhdGgoX3NjcmlwdE5hbWUpKSsiLyJ9cmVhZEJpbmFyeT1maWxlbmFtZT0+e2ZpbGVuYW1lPWlzRmlsZVVSSShmaWxlbmFtZSk/bmV3IFVSTChmaWxlbmFtZSk6ZmlsZW5hbWU7dmFyIHJldD1mcy5yZWFkRmlsZVN5bmMoZmlsZW5hbWUpO3JldHVybiByZXR9O3JlYWRBc3luYz1hc3luYyhmaWxlbmFtZSxiaW5hcnk9dHJ1ZSk9PntmaWxlbmFtZT1pc0ZpbGVVUkkoZmlsZW5hbWUpP25ldyBVUkwoZmlsZW5hbWUpOmZpbGVuYW1lO3ZhciByZXQ9ZnMucmVhZEZpbGVTeW5jKGZpbGVuYW1lLGJpbmFyeT91bmRlZmluZWQ6InV0ZjgiKTtyZXR1cm4gcmV0fTtpZihwcm9jZXNzLmFyZ3YubGVuZ3RoPjEpe3RoaXNQcm9ncmFtPXByb2Nlc3MuYXJndlsxXS5yZXBsYWNlKC9cXC9nLCIvIil9YXJndW1lbnRzXz1wcm9jZXNzLmFyZ3Yuc2xpY2UoMik7cXVpdF89KHN0YXR1cyx0b1Rocm93KT0+e3Byb2Nlc3MuZXhpdENvZGU9c3RhdHVzO3Rocm93IHRvVGhyb3d9fWVsc2UgaWYoRU5WSVJPTk1FTlRfSVNfV0VCfHxFTlZJUk9OTUVOVF9JU19XT1JLRVIpe3RyeXtzY3JpcHREaXJlY3Rvcnk9bmV3IFVSTCgiLiIsX3NjcmlwdE5hbWUpLmhyZWZ9Y2F0Y2h7fWlmKCFFTlZJUk9OTUVOVF9JU19OT0RFKXtpZihFTlZJUk9OTUVOVF9JU19XT1JLRVIpe3JlYWRCaW5hcnk9dXJsPT57dmFyIHhocj1uZXcgWE1MSHR0cFJlcXVlc3Q7eGhyLm9wZW4oIkdFVCIsdXJsLGZhbHNlKTt4aHIucmVzcG9uc2VUeXBlPSJhcnJheWJ1ZmZlciI7eGhyLnNlbmQobnVsbCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KHhoci5yZXNwb25zZSl9fXJlYWRBc3luYz1hc3luYyB1cmw9Pnt2YXIgcmVzcG9uc2U9YXdhaXQgZmV0Y2godXJsLHtjcmVkZW50aWFsczoic2FtZS1vcmlnaW4ifSk7aWYocmVzcG9uc2Uub2spe3JldHVybiByZXNwb25zZS5hcnJheUJ1ZmZlcigpfXRocm93IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXMrIiA6ICIrcmVzcG9uc2UudXJsKX19fWVsc2V7fXZhciBkZWZhdWx0UHJpbnQ9Y29uc29sZS5sb2cuYmluZChjb25zb2xlKTt2YXIgZGVmYXVsdFByaW50RXJyPWNvbnNvbGUuZXJyb3IuYmluZChjb25zb2xlKTtpZihFTlZJUk9OTUVOVF9JU19OT0RFKXt2YXIgdXRpbHM9cmVxdWlyZSgidXRpbCIpO3ZhciBzdHJpbmdpZnk9YT0+dHlwZW9mIGE9PSJvYmplY3QiP3V0aWxzLmluc3BlY3QoYSk6YTtkZWZhdWx0UHJpbnQ9KC4uLmFyZ3MpPT5mcy53cml0ZVN5bmMoMSxhcmdzLm1hcChzdHJpbmdpZnkpLmpvaW4oIiAiKSsiXG4iKTtkZWZhdWx0UHJpbnRFcnI9KC4uLmFyZ3MpPT5mcy53cml0ZVN5bmMoMixhcmdzLm1hcChzdHJpbmdpZnkpLmpvaW4oIiAiKSsiXG4iKX12YXIgb3V0PWRlZmF1bHRQcmludDt2YXIgZXJyPWRlZmF1bHRQcmludEVycjt2YXIgd2FzbUJpbmFyeTt2YXIgd2FzbU1vZHVsZTt2YXIgQUJPUlQ9ZmFsc2U7dmFyIEVYSVRTVEFUVVM7dmFyIGlzRmlsZVVSST1maWxlbmFtZT0+ZmlsZW5hbWUuc3RhcnRzV2l0aCgiZmlsZTovLyIpO2Z1bmN0aW9uIGdyb3dNZW1WaWV3cygpe2lmKHdhc21NZW1vcnkuYnVmZmVyIT1IRUFQOC5idWZmZXIpe3VwZGF0ZU1lbW9yeVZpZXdzKCl9fXZhciByZWFkeVByb21pc2VSZXNvbHZlLHJlYWR5UHJvbWlzZVJlamVjdDtpZihFTlZJUk9OTUVOVF9JU19OT0RFJiZFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt2YXIgcGFyZW50UG9ydD13b3JrZXJfdGhyZWFkc1sicGFyZW50UG9ydCJdO3BhcmVudFBvcnQub24oIm1lc3NhZ2UiLG1zZz0+Z2xvYmFsLm9ubWVzc2FnZT8uKHtkYXRhOm1zZ30pKTtPYmplY3QuYXNzaWduKGdsb2JhbFRoaXMse3NlbGY6Z2xvYmFsLHBvc3RNZXNzYWdlOm1zZz0+cGFyZW50UG9ydFsicG9zdE1lc3NhZ2UiXShtc2cpfSk7cHJvY2Vzcy5vbigidW5jYXVnaHRFeGNlcHRpb24iLGVycj0+e3Bvc3RNZXNzYWdlKHtjbWQ6InVuY2F1Z2h0RXhjZXB0aW9uIixlcnJvcjplcnJ9KTtwcm9jZXNzLmV4aXQoMSl9KX12YXIgc3RhcnRXb3JrZXI7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7dmFyIGluaXRpYWxpemVkSlM9ZmFsc2U7c2VsZi5vbnVuaGFuZGxlZHJlamVjdGlvbj1lPT57dGhyb3cgZS5yZWFzb258fGV9O2Z1bmN0aW9uIGhhbmRsZU1lc3NhZ2UoZSl7dHJ5e3ZhciBtc2dEYXRhPWVbImRhdGEiXTt2YXIgY21kPW1zZ0RhdGEuY21kO2lmKGNtZD09PSJsb2FkIil7bGV0IG1lc3NhZ2VRdWV1ZT1bXTtzZWxmLm9ubWVzc2FnZT1lPT5tZXNzYWdlUXVldWUucHVzaChlKTtzdGFydFdvcmtlcj0oKT0+e3Bvc3RNZXNzYWdlKHtjbWQ6ImxvYWRlZCJ9KTtmb3IobGV0IG1zZyBvZiBtZXNzYWdlUXVldWUpe2hhbmRsZU1lc3NhZ2UobXNnKX1zZWxmLm9ubWVzc2FnZT1oYW5kbGVNZXNzYWdlfTtmb3IoY29uc3QgaGFuZGxlciBvZiBtc2dEYXRhLmhhbmRsZXJzKXtpZighTW9kdWxlW2hhbmRsZXJdfHxNb2R1bGVbaGFuZGxlcl0ucHJveHkpe01vZHVsZVtoYW5kbGVyXT0oLi4uYXJncyk9Pntwb3N0TWVzc2FnZSh7Y21kOiJjYWxsSGFuZGxlciIsaGFuZGxlcixhcmdzfSl9O2lmKGhhbmRsZXI9PSJwcmludCIpb3V0PU1vZHVsZVtoYW5kbGVyXTtpZihoYW5kbGVyPT0icHJpbnRFcnIiKWVycj1Nb2R1bGVbaGFuZGxlcl19fXdhc21NZW1vcnk9bXNnRGF0YS53YXNtTWVtb3J5O3VwZGF0ZU1lbW9yeVZpZXdzKCk7d2FzbU1vZHVsZT1tc2dEYXRhLndhc21Nb2R1bGU7Y3JlYXRlV2FzbSgpO3J1bigpfWVsc2UgaWYoY21kPT09InJ1biIpe2VzdGFibGlzaFN0YWNrU3BhY2UobXNnRGF0YS5wdGhyZWFkX3B0cik7X19lbXNjcmlwdGVuX3RocmVhZF9pbml0KG1zZ0RhdGEucHRocmVhZF9wdHIsMCwwLDEsMCwwKTtQVGhyZWFkLnRocmVhZEluaXRUTFMoKTtfX2Vtc2NyaXB0ZW5fdGhyZWFkX21haWxib3hfYXdhaXQobXNnRGF0YS5wdGhyZWFkX3B0cik7aWYoIWluaXRpYWxpemVkSlMpe2luaXRpYWxpemVkSlM9dHJ1ZX10cnl7aW52b2tlRW50cnlQb2ludChtc2dEYXRhLnN0YXJ0X3JvdXRpbmUsbXNnRGF0YS5hcmcpfWNhdGNoKGV4KXtpZihleCE9InVud2luZCIpe3Rocm93IGV4fX19ZWxzZSBpZihtc2dEYXRhLnRhcmdldD09PSJzZXRpbW1lZGlhdGUiKXt9ZWxzZSBpZihjbWQ9PT0iY2hlY2tNYWlsYm94Iil7aWYoaW5pdGlhbGl6ZWRKUyl7Y2hlY2tNYWlsYm94KCl9fWVsc2UgaWYoY21kKXtlcnIoYHdvcmtlcjogcmVjZWl2ZWQgdW5rbm93biBjb21tYW5kICR7Y21kfWApO2Vycihtc2dEYXRhKX19Y2F0Y2goZXgpe19fZW1zY3JpcHRlbl90aHJlYWRfY3Jhc2hlZCgpO3Rocm93IGV4fX1zZWxmLm9ubWVzc2FnZT1oYW5kbGVNZXNzYWdlfXZhciB3YXNtTWVtb3J5O3ZhciBIRUFQOCxIRUFQVTgsSEVBUDE2LEhFQVBVMTYsSEVBUDMyLEhFQVBVMzIsSEVBUEYzMixIRUFQRjY0O3ZhciBIRUFQNjQsSEVBUFU2NDt2YXIgcnVudGltZUluaXRpYWxpemVkPWZhbHNlO2Z1bmN0aW9uIHVwZGF0ZU1lbW9yeVZpZXdzKCl7dmFyIGI9d2FzbU1lbW9yeS5idWZmZXI7SEVBUDg9bmV3IEludDhBcnJheShiKTtIRUFQMTY9bmV3IEludDE2QXJyYXkoYik7SEVBUFU4PW5ldyBVaW50OEFycmF5KGIpO0hFQVBVMTY9bmV3IFVpbnQxNkFycmF5KGIpO0hFQVAzMj1uZXcgSW50MzJBcnJheShiKTtIRUFQVTMyPW5ldyBVaW50MzJBcnJheShiKTtIRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYik7SEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGIpO0hFQVA2ND1uZXcgQmlnSW50NjRBcnJheShiKTtIRUFQVTY0PW5ldyBCaWdVaW50NjRBcnJheShiKX1mdW5jdGlvbiBpbml0TWVtb3J5KCl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7cmV0dXJufWlmKE1vZHVsZVsid2FzbU1lbW9yeSJdKXt3YXNtTWVtb3J5PU1vZHVsZVsid2FzbU1lbW9yeSJdfWVsc2V7dmFyIElOSVRJQUxfTUVNT1JZPU1vZHVsZVsiSU5JVElBTF9NRU1PUlkiXXx8NjcxMDg4NjQ7d2FzbU1lbW9yeT1uZXcgV2ViQXNzZW1ibHkuTWVtb3J5KHtpbml0aWFsOklOSVRJQUxfTUVNT1JZLzY1NTM2LG1heGltdW06NjU1MzYsc2hhcmVkOnRydWV9KX11cGRhdGVNZW1vcnlWaWV3cygpfWZ1bmN0aW9uIHByZVJ1bigpe2lmKE1vZHVsZVsicHJlUnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInByZVJ1biJdPT0iZnVuY3Rpb24iKU1vZHVsZVsicHJlUnVuIl09W01vZHVsZVsicHJlUnVuIl1dO3doaWxlKE1vZHVsZVsicHJlUnVuIl0ubGVuZ3RoKXthZGRPblByZVJ1bihNb2R1bGVbInByZVJ1biJdLnNoaWZ0KCkpfX1jYWxsUnVudGltZUNhbGxiYWNrcyhvblByZVJ1bnMpfWZ1bmN0aW9uIGluaXRSdW50aW1lKCl7cnVudGltZUluaXRpYWxpemVkPXRydWU7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRClyZXR1cm4gc3RhcnRXb3JrZXIoKTt3YXNtRXhwb3J0c1sibyJdKCl9ZnVuY3Rpb24gcG9zdFJ1bigpe2lmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpe3JldHVybn1pZihNb2R1bGVbInBvc3RSdW4iXSl7aWYodHlwZW9mIE1vZHVsZVsicG9zdFJ1biJdPT0iZnVuY3Rpb24iKU1vZHVsZVsicG9zdFJ1biJdPVtNb2R1bGVbInBvc3RSdW4iXV07d2hpbGUoTW9kdWxlWyJwb3N0UnVuIl0ubGVuZ3RoKXthZGRPblBvc3RSdW4oTW9kdWxlWyJwb3N0UnVuIl0uc2hpZnQoKSl9fWNhbGxSdW50aW1lQ2FsbGJhY2tzKG9uUG9zdFJ1bnMpfWZ1bmN0aW9uIGFib3J0KHdoYXQpe01vZHVsZVsib25BYm9ydCJdPy4od2hhdCk7d2hhdD0iQWJvcnRlZCgiK3doYXQrIikiO2Vycih3aGF0KTtBQk9SVD10cnVlO3doYXQrPSIuIEJ1aWxkIHdpdGggLXNBU1NFUlRJT05TIGZvciBtb3JlIGluZm8uIjt2YXIgZT1uZXcgV2ViQXNzZW1ibHkuUnVudGltZUVycm9yKHdoYXQpO3JlYWR5UHJvbWlzZVJlamVjdD8uKGUpO3Rocm93IGV9dmFyIHdhc21CaW5hcnlGaWxlO2Z1bmN0aW9uIGZpbmRXYXNtQmluYXJ5KCl7aWYoTW9kdWxlWyJsb2NhdGVGaWxlIl0pe3JldHVybiBsb2NhdGVGaWxlKCJza2FpbmV0X2tlcm5lbHNfbXQud2FzbSIpfXRyeXtyZXR1cm4gbmV3IFVSTCgic2thaW5ldF9rZXJuZWxzX210Lndhc20iLGltcG9ydC5tZXRhLnVybCkuaHJlZn1jYXRjaChlKXtyZXR1cm4gInNrYWluZXRfa2VybmVsc19tdC53YXNtIn19ZnVuY3Rpb24gZ2V0QmluYXJ5U3luYyhmaWxlKXtpZihmaWxlPT13YXNtQmluYXJ5RmlsZSYmd2FzbUJpbmFyeSl7cmV0dXJuIG5ldyBVaW50OEFycmF5KHdhc21CaW5hcnkpfWlmKHJlYWRCaW5hcnkpe3JldHVybiByZWFkQmluYXJ5KGZpbGUpfXRocm93ImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1hc3luYyBmdW5jdGlvbiBnZXRXYXNtQmluYXJ5KGJpbmFyeUZpbGUpe2lmKCF3YXNtQmluYXJ5KXt0cnl7dmFyIHJlc3BvbnNlPWF3YWl0IHJlYWRBc3luYyhiaW5hcnlGaWxlKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkocmVzcG9uc2UpfWNhdGNoe319cmV0dXJuIGdldEJpbmFyeVN5bmMoYmluYXJ5RmlsZSl9YXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGVBcnJheUJ1ZmZlcihiaW5hcnlGaWxlLGltcG9ydHMpe3RyeXt2YXIgYmluYXJ5PWF3YWl0IGdldFdhc21CaW5hcnkoYmluYXJ5RmlsZSk7dmFyIGluc3RhbmNlPWF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGJpbmFyeSxpbXBvcnRzKTtyZXR1cm4gaW5zdGFuY2V9Y2F0Y2gocmVhc29uKXtlcnIoYGZhaWxlZCB0byBhc3luY2hyb25vdXNseSBwcmVwYXJlIHdhc206ICR7cmVhc29ufWApO2Fib3J0KHJlYXNvbil9fWFzeW5jIGZ1bmN0aW9uIGluc3RhbnRpYXRlQXN5bmMoYmluYXJ5LGJpbmFyeUZpbGUsaW1wb3J0cyl7aWYoIWJpbmFyeSYmIUVOVklST05NRU5UX0lTX05PREUpe3RyeXt2YXIgcmVzcG9uc2U9ZmV0Y2goYmluYXJ5RmlsZSx7Y3JlZGVudGlhbHM6InNhbWUtb3JpZ2luIn0pO3ZhciBpbnN0YW50aWF0aW9uUmVzdWx0PWF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nKHJlc3BvbnNlLGltcG9ydHMpO3JldHVybiBpbnN0YW50aWF0aW9uUmVzdWx0fWNhdGNoKHJlYXNvbil7ZXJyKGB3YXNtIHN0cmVhbWluZyBjb21waWxlIGZhaWxlZDogJHtyZWFzb259YCk7ZXJyKCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvbiIpfX1yZXR1cm4gaW5zdGFudGlhdGVBcnJheUJ1ZmZlcihiaW5hcnlGaWxlLGltcG9ydHMpfWZ1bmN0aW9uIGdldFdhc21JbXBvcnRzKCl7YXNzaWduV2FzbUltcG9ydHMoKTtyZXR1cm57YTp3YXNtSW1wb3J0c319YXN5bmMgZnVuY3Rpb24gY3JlYXRlV2FzbSgpe2Z1bmN0aW9uIHJlY2VpdmVJbnN0YW5jZShpbnN0YW5jZSxtb2R1bGUpe3dhc21FeHBvcnRzPWluc3RhbmNlLmV4cG9ydHM7d2FzbUV4cG9ydHM9YXBwbHlTaWduYXR1cmVDb252ZXJzaW9ucyh3YXNtRXhwb3J0cyk7cmVnaXN0ZXJUTFNJbml0KHdhc21FeHBvcnRzWyJLIl0pO3dhc21UYWJsZT13YXNtRXhwb3J0c1siciJdO3dhc21Nb2R1bGU9bW9kdWxlO2Fzc2lnbldhc21FeHBvcnRzKHdhc21FeHBvcnRzKTtyZXR1cm4gd2FzbUV4cG9ydHN9ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KXtyZXR1cm4gcmVjZWl2ZUluc3RhbmNlKHJlc3VsdFsiaW5zdGFuY2UiXSxyZXN1bHRbIm1vZHVsZSJdKX12YXIgaW5mbz1nZXRXYXNtSW1wb3J0cygpO2lmKE1vZHVsZVsiaW5zdGFudGlhdGVXYXNtIl0pe3JldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSxyZWplY3QpPT57TW9kdWxlWyJpbnN0YW50aWF0ZVdhc20iXShpbmZvLChtb2QsaW5zdCk9PntyZXNvbHZlKHJlY2VpdmVJbnN0YW5jZShtb2QsaW5zdCkpfSl9KX1pZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt2YXIgaW5zdGFuY2U9bmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKHdhc21Nb2R1bGUsZ2V0V2FzbUltcG9ydHMoKSk7cmV0dXJuIHJlY2VpdmVJbnN0YW5jZShpbnN0YW5jZSx3YXNtTW9kdWxlKX13YXNtQmluYXJ5RmlsZT8/PWZpbmRXYXNtQmluYXJ5KCk7dmFyIHJlc3VsdD1hd2FpdCBpbnN0YW50aWF0ZUFzeW5jKHdhc21CaW5hcnksd2FzbUJpbmFyeUZpbGUsaW5mbyk7dmFyIGV4cG9ydHM9cmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KTtyZXR1cm4gZXhwb3J0c31jbGFzcyBFeGl0U3RhdHVze25hbWU9IkV4aXRTdGF0dXMiO2NvbnN0cnVjdG9yKHN0YXR1cyl7dGhpcy5tZXNzYWdlPWBQcm9ncmFtIHRlcm1pbmF0ZWQgd2l0aCBleGl0KCR7c3RhdHVzfSlgO3RoaXMuc3RhdHVzPXN0YXR1c319dmFyIHRlcm1pbmF0ZVdvcmtlcj13b3JrZXI9Pnt3b3JrZXIudGVybWluYXRlKCk7d29ya2VyLm9ubWVzc2FnZT1lPT57fX07dmFyIGNsZWFudXBUaHJlYWQ9cHRocmVhZF9wdHI9Pnt2YXIgd29ya2VyPVBUaHJlYWQucHRocmVhZHNbcHRocmVhZF9wdHJdO1BUaHJlYWQucmV0dXJuV29ya2VyVG9Qb29sKHdvcmtlcil9O3ZhciBjYWxsUnVudGltZUNhbGxiYWNrcz1jYWxsYmFja3M9Pnt3aGlsZShjYWxsYmFja3MubGVuZ3RoPjApe2NhbGxiYWNrcy5zaGlmdCgpKE1vZHVsZSl9fTt2YXIgb25QcmVSdW5zPVtdO3ZhciBhZGRPblByZVJ1bj1jYj0+b25QcmVSdW5zLnB1c2goY2IpO3ZhciBydW5EZXBlbmRlbmNpZXM9MDt2YXIgZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7dmFyIHJlbW92ZVJ1bkRlcGVuZGVuY3k9aWQ9PntydW5EZXBlbmRlbmNpZXMtLTtNb2R1bGVbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXT8uKHJ1bkRlcGVuZGVuY2llcyk7aWYocnVuRGVwZW5kZW5jaWVzPT0wKXtpZihkZXBlbmRlbmNpZXNGdWxmaWxsZWQpe3ZhciBjYWxsYmFjaz1kZXBlbmRlbmNpZXNGdWxmaWxsZWQ7ZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7Y2FsbGJhY2soKX19fTt2YXIgYWRkUnVuRGVwZW5kZW5jeT1pZD0+e3J1bkRlcGVuZGVuY2llcysrO01vZHVsZVsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdPy4ocnVuRGVwZW5kZW5jaWVzKX07dmFyIHNwYXduVGhyZWFkPXRocmVhZFBhcmFtcz0+e3ZhciB3b3JrZXI9UFRocmVhZC5nZXROZXdXb3JrZXIoKTtpZighd29ya2VyKXtyZXR1cm4gNn1QVGhyZWFkLnJ1bm5pbmdXb3JrZXJzLnB1c2god29ya2VyKTtQVGhyZWFkLnB0aHJlYWRzW3RocmVhZFBhcmFtcy5wdGhyZWFkX3B0cl09d29ya2VyO3dvcmtlci5wdGhyZWFkX3B0cj10aHJlYWRQYXJhbXMucHRocmVhZF9wdHI7dmFyIG1zZz17Y21kOiJydW4iLHN0YXJ0X3JvdXRpbmU6dGhyZWFkUGFyYW1zLnN0YXJ0Um91dGluZSxhcmc6dGhyZWFkUGFyYW1zLmFyZyxwdGhyZWFkX3B0cjp0aHJlYWRQYXJhbXMucHRocmVhZF9wdHJ9O2lmKEVOVklST05NRU5UX0lTX05PREUpe3dvcmtlci51bnJlZigpfXdvcmtlci5wb3N0TWVzc2FnZShtc2csdGhyZWFkUGFyYW1zLnRyYW5zZmVyTGlzdCk7cmV0dXJuIDB9O3ZhciBydW50aW1lS2VlcGFsaXZlQ291bnRlcj0wO3ZhciBrZWVwUnVudGltZUFsaXZlPSgpPT5ub0V4aXRSdW50aW1lfHxydW50aW1lS2VlcGFsaXZlQ291bnRlcj4wO3ZhciBzdGFja1NhdmU9KCk9Pl9lbXNjcmlwdGVuX3N0YWNrX2dldF9jdXJyZW50KCk7dmFyIHN0YWNrUmVzdG9yZT12YWw9Pl9fZW1zY3JpcHRlbl9zdGFja19yZXN0b3JlKHZhbCk7dmFyIHN0YWNrQWxsb2M9c3o9Pl9fZW1zY3JpcHRlbl9zdGFja19hbGxvYyhzeik7dmFyIHByb3h5VG9NYWluVGhyZWFkPShmdW5jSW5kZXgsZW1Bc21BZGRyLHN5bmMsLi4uY2FsbEFyZ3MpPT57dmFyIHNlcmlhbGl6ZWROdW1DYWxsQXJncz1jYWxsQXJncy5sZW5ndGgqMjt2YXIgc3A9c3RhY2tTYXZlKCk7dmFyIGFyZ3M9c3RhY2tBbGxvYyhzZXJpYWxpemVkTnVtQ2FsbEFyZ3MqOCk7dmFyIGI9YXJncz4+PjM7Zm9yKHZhciBpPTA7aTxjYWxsQXJncy5sZW5ndGg7aSsrKXt2YXIgYXJnPWNhbGxBcmdzW2ldO2lmKHR5cGVvZiBhcmc9PSJiaWdpbnQiKXsoZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaT4+PjBdPTFuOyhncm93TWVtVmlld3MoKSxIRUFQNjQpW2IrMippKzE+Pj4wXT1hcmd9ZWxzZXsoZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaT4+PjBdPTBuOyhncm93TWVtVmlld3MoKSxIRUFQRjY0KVtiKzIqaSsxPj4+MF09YXJnfX12YXIgcnRuPV9fZW1zY3JpcHRlbl9ydW5fanNfb25fbWFpbl90aHJlYWQoZnVuY0luZGV4LGVtQXNtQWRkcixzZXJpYWxpemVkTnVtQ2FsbEFyZ3MsYXJncyxzeW5jKTtzdGFja1Jlc3RvcmUoc3ApO3JldHVybiBydG59O2Z1bmN0aW9uIF9wcm9jX2V4aXQoY29kZSl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRClyZXR1cm4gcHJveHlUb01haW5UaHJlYWQoMCwwLDEsY29kZSk7RVhJVFNUQVRVUz1jb2RlO2lmKCFrZWVwUnVudGltZUFsaXZlKCkpe1BUaHJlYWQudGVybWluYXRlQWxsVGhyZWFkcygpO01vZHVsZVsib25FeGl0Il0/Lihjb2RlKTtBQk9SVD10cnVlfXF1aXRfKGNvZGUsbmV3IEV4aXRTdGF0dXMoY29kZSkpfWZ1bmN0aW9uIGV4aXRPbk1haW5UaHJlYWQocmV0dXJuQ29kZSl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRClyZXR1cm4gcHJveHlUb01haW5UaHJlYWQoMSwwLDAscmV0dXJuQ29kZSk7X2V4aXQocmV0dXJuQ29kZSl9dmFyIGV4aXRKUz0oc3RhdHVzLGltcGxpY2l0KT0+e0VYSVRTVEFUVVM9c3RhdHVzO2lmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpe2V4aXRPbk1haW5UaHJlYWQoc3RhdHVzKTt0aHJvdyJ1bndpbmQifV9wcm9jX2V4aXQoc3RhdHVzKX07dmFyIF9leGl0PWV4aXRKUzt2YXIgUFRocmVhZD17dW51c2VkV29ya2VyczpbXSxydW5uaW5nV29ya2VyczpbXSx0bHNJbml0RnVuY3Rpb25zOltdLHB0aHJlYWRzOnt9LGluaXQoKXtpZighRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7UFRocmVhZC5pbml0TWFpblRocmVhZCgpfX0saW5pdE1haW5UaHJlYWQoKXt2YXIgcHRocmVhZFBvb2xTaXplPTQ7d2hpbGUocHRocmVhZFBvb2xTaXplLS0pe1BUaHJlYWQuYWxsb2NhdGVVbnVzZWRXb3JrZXIoKX1hZGRPblByZVJ1bihhc3luYygpPT57dmFyIHB0aHJlYWRQb29sUmVhZHk9UFRocmVhZC5sb2FkV2FzbU1vZHVsZVRvQWxsV29ya2VycygpO2FkZFJ1bkRlcGVuZGVuY3koImxvYWRpbmctd29ya2VycyIpO2F3YWl0IHB0aHJlYWRQb29sUmVhZHk7cmVtb3ZlUnVuRGVwZW5kZW5jeSgibG9hZGluZy13b3JrZXJzIil9KX0sdGVybWluYXRlQWxsVGhyZWFkczooKT0+e2Zvcih2YXIgd29ya2VyIG9mIFBUaHJlYWQucnVubmluZ1dvcmtlcnMpe3Rlcm1pbmF0ZVdvcmtlcih3b3JrZXIpfWZvcih2YXIgd29ya2VyIG9mIFBUaHJlYWQudW51c2VkV29ya2Vycyl7dGVybWluYXRlV29ya2VyKHdvcmtlcil9UFRocmVhZC51bnVzZWRXb3JrZXJzPVtdO1BUaHJlYWQucnVubmluZ1dvcmtlcnM9W107UFRocmVhZC5wdGhyZWFkcz17fX0scmV0dXJuV29ya2VyVG9Qb29sOndvcmtlcj0+e3ZhciBwdGhyZWFkX3B0cj13b3JrZXIucHRocmVhZF9wdHI7ZGVsZXRlIFBUaHJlYWQucHRocmVhZHNbcHRocmVhZF9wdHJdO1BUaHJlYWQudW51c2VkV29ya2Vycy5wdXNoKHdvcmtlcik7UFRocmVhZC5ydW5uaW5nV29ya2Vycy5zcGxpY2UoUFRocmVhZC5ydW5uaW5nV29ya2Vycy5pbmRleE9mKHdvcmtlciksMSk7d29ya2VyLnB0aHJlYWRfcHRyPTA7X19lbXNjcmlwdGVuX3RocmVhZF9mcmVlX2RhdGEocHRocmVhZF9wdHIpfSx0aHJlYWRJbml0VExTKCl7UFRocmVhZC50bHNJbml0RnVuY3Rpb25zLmZvckVhY2goZj0+ZigpKX0sbG9hZFdhc21Nb2R1bGVUb1dvcmtlcjp3b3JrZXI9Pm5ldyBQcm9taXNlKG9uRmluaXNoZWRMb2FkaW5nPT57d29ya2VyLm9ubWVzc2FnZT1lPT57dmFyIGQ9ZVsiZGF0YSJdO3ZhciBjbWQ9ZC5jbWQ7aWYoZC50YXJnZXRUaHJlYWQmJmQudGFyZ2V0VGhyZWFkIT1fcHRocmVhZF9zZWxmKCkpe3ZhciB0YXJnZXRXb3JrZXI9UFRocmVhZC5wdGhyZWFkc1tkLnRhcmdldFRocmVhZF07aWYodGFyZ2V0V29ya2VyKXt0YXJnZXRXb3JrZXIucG9zdE1lc3NhZ2UoZCxkLnRyYW5zZmVyTGlzdCl9ZWxzZXtlcnIoYEludGVybmFsIGVycm9yISBXb3JrZXIgc2VudCBhIG1lc3NhZ2UgIiR7Y21kfSIgdG8gdGFyZ2V0IHB0aHJlYWQgJHtkLnRhcmdldFRocmVhZH0sIGJ1dCB0aGF0IHRocmVhZCBubyBsb25nZXIgZXhpc3RzIWApfXJldHVybn1pZihjbWQ9PT0iY2hlY2tNYWlsYm94Iil7Y2hlY2tNYWlsYm94KCl9ZWxzZSBpZihjbWQ9PT0ic3Bhd25UaHJlYWQiKXtzcGF3blRocmVhZChkKX1lbHNlIGlmKGNtZD09PSJjbGVhbnVwVGhyZWFkIil7Y2FsbFVzZXJDYWxsYmFjaygoKT0+Y2xlYW51cFRocmVhZChkLnRocmVhZCkpfWVsc2UgaWYoY21kPT09ImxvYWRlZCIpe3dvcmtlci5sb2FkZWQ9dHJ1ZTtpZihFTlZJUk9OTUVOVF9JU19OT0RFJiYhd29ya2VyLnB0aHJlYWRfcHRyKXt3b3JrZXIudW5yZWYoKX1vbkZpbmlzaGVkTG9hZGluZyh3b3JrZXIpfWVsc2UgaWYoZC50YXJnZXQ9PT0ic2V0aW1tZWRpYXRlIil7d29ya2VyLnBvc3RNZXNzYWdlKGQpfWVsc2UgaWYoY21kPT09InVuY2F1Z2h0RXhjZXB0aW9uIil7d29ya2VyLm9uZXJyb3IoZC5lcnJvcil9ZWxzZSBpZihjbWQ9PT0iY2FsbEhhbmRsZXIiKXtNb2R1bGVbZC5oYW5kbGVyXSguLi5kLmFyZ3MpfWVsc2UgaWYoY21kKXtlcnIoYHdvcmtlciBzZW50IGFuIHVua25vd24gY29tbWFuZCAke2NtZH1gKX19O3dvcmtlci5vbmVycm9yPWU9Pnt2YXIgbWVzc2FnZT0id29ya2VyIHNlbnQgYW4gZXJyb3IhIjtlcnIoYCR7bWVzc2FnZX0gJHtlLmZpbGVuYW1lfToke2UubGluZW5vfTogJHtlLm1lc3NhZ2V9YCk7dGhyb3cgZX07aWYoRU5WSVJPTk1FTlRfSVNfTk9ERSl7d29ya2VyLm9uKCJtZXNzYWdlIixkYXRhPT53b3JrZXIub25tZXNzYWdlKHtkYXRhfSkpO3dvcmtlci5vbigiZXJyb3IiLGU9Pndvcmtlci5vbmVycm9yKGUpKX12YXIgaGFuZGxlcnM9W107dmFyIGtub3duSGFuZGxlcnM9WyJvbkV4aXQiLCJvbkFib3J0IiwicHJpbnQiLCJwcmludEVyciJdO2Zvcih2YXIgaGFuZGxlciBvZiBrbm93bkhhbmRsZXJzKXtpZihNb2R1bGUucHJvcGVydHlJc0VudW1lcmFibGUoaGFuZGxlcikpe2hhbmRsZXJzLnB1c2goaGFuZGxlcil9fXdvcmtlci5wb3N0TWVzc2FnZSh7Y21kOiJsb2FkIixoYW5kbGVycyx3YXNtTWVtb3J5LHdhc21Nb2R1bGV9KX0pLGFzeW5jIGxvYWRXYXNtTW9kdWxlVG9BbGxXb3JrZXJzKCl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7cmV0dXJufWxldCBwdGhyZWFkUG9vbFJlYWR5PVByb21pc2UuYWxsKFBUaHJlYWQudW51c2VkV29ya2Vycy5tYXAoUFRocmVhZC5sb2FkV2FzbU1vZHVsZVRvV29ya2VyKSk7cmV0dXJuIHB0aHJlYWRQb29sUmVhZHl9LGFsbG9jYXRlVW51c2VkV29ya2VyKCl7dmFyIHdvcmtlcjtpZihNb2R1bGVbIm1haW5TY3JpcHRVcmxPckJsb2IiXSl7dmFyIHB0aHJlYWRNYWluSnM9TW9kdWxlWyJtYWluU2NyaXB0VXJsT3JCbG9iIl07aWYodHlwZW9mIHB0aHJlYWRNYWluSnMhPSJzdHJpbmciKXtwdGhyZWFkTWFpbkpzPVVSTC5jcmVhdGVPYmplY3RVUkwocHRocmVhZE1haW5Kcyl9d29ya2VyPW5ldyBXb3JrZXIoRU5WSVJPTk1FTlRfSVNfTk9ERSYmdHlwZW9mIHB0aHJlYWRNYWluSnM9PSJzdHJpbmciJiZwdGhyZWFkTWFpbkpzLnN0YXJ0c1dpdGgoImRhdGE6Iik/bmV3IFVSTChwdGhyZWFkTWFpbkpzKTpwdGhyZWFkTWFpbkpzLHt0eXBlOiJtb2R1bGUiLHdvcmtlckRhdGE6ImVtLXB0aHJlYWQiLG5hbWU6ImVtLXB0aHJlYWQifSl9ZWxzZSB3b3JrZXI9bmV3IFdvcmtlcihuZXcgVVJMKCJza2FpbmV0X2tlcm5lbHNfbXQubWpzIixpbXBvcnQubWV0YS51cmwpLHt0eXBlOiJtb2R1bGUiLHdvcmtlckRhdGE6ImVtLXB0aHJlYWQiLG5hbWU6ImVtLXB0aHJlYWQifSk7UFRocmVhZC51bnVzZWRXb3JrZXJzLnB1c2god29ya2VyKX0sZ2V0TmV3V29ya2VyKCl7aWYoUFRocmVhZC51bnVzZWRXb3JrZXJzLmxlbmd0aD09MCl7UFRocmVhZC5hbGxvY2F0ZVVudXNlZFdvcmtlcigpO1BUaHJlYWQubG9hZFdhc21Nb2R1bGVUb1dvcmtlcihQVGhyZWFkLnVudXNlZFdvcmtlcnNbMF0pfXJldHVybiBQVGhyZWFkLnVudXNlZFdvcmtlcnMucG9wKCl9fTt2YXIgb25Qb3N0UnVucz1bXTt2YXIgYWRkT25Qb3N0UnVuPWNiPT5vblBvc3RSdW5zLnB1c2goY2IpO2Z1bmN0aW9uIGVzdGFibGlzaFN0YWNrU3BhY2UocHRocmVhZF9wdHIpe3ZhciBzdGFja0hpZ2g9KGdyb3dNZW1WaWV3cygpLEhFQVBVMzIpW3B0aHJlYWRfcHRyKzUyPj4+Mj4+PjBdO3ZhciBzdGFja1NpemU9KGdyb3dNZW1WaWV3cygpLEhFQVBVMzIpW3B0aHJlYWRfcHRyKzU2Pj4+Mj4+PjBdO3ZhciBzdGFja0xvdz1zdGFja0hpZ2gtc3RhY2tTaXplO19lbXNjcmlwdGVuX3N0YWNrX3NldF9saW1pdHMoc3RhY2tIaWdoLHN0YWNrTG93KTtzdGFja1Jlc3RvcmUoc3RhY2tIaWdoKX12YXIgd2FzbVRhYmxlTWlycm9yPVtdO3ZhciB3YXNtVGFibGU7dmFyIGdldFdhc21UYWJsZUVudHJ5PWZ1bmNQdHI9Pnt2YXIgZnVuYz13YXNtVGFibGVNaXJyb3JbZnVuY1B0cl07aWYoIWZ1bmMpe3dhc21UYWJsZU1pcnJvcltmdW5jUHRyXT1mdW5jPXdhc21UYWJsZS5nZXQoZnVuY1B0cil9cmV0dXJuIGZ1bmN9O3ZhciBpbnZva2VFbnRyeVBvaW50PShwdHIsYXJnKT0+e3J1bnRpbWVLZWVwYWxpdmVDb3VudGVyPTA7bm9FeGl0UnVudGltZT0wO3ZhciByZXN1bHQ9Z2V0V2FzbVRhYmxlRW50cnkocHRyKShhcmcpO2Z1bmN0aW9uIGZpbmlzaChyZXN1bHQpe2lmKGtlZXBSdW50aW1lQWxpdmUoKSl7RVhJVFNUQVRVUz1yZXN1bHQ7cmV0dXJufV9fZW1zY3JpcHRlbl90aHJlYWRfZXhpdChyZXN1bHQpfWZpbmlzaChyZXN1bHQpfTt2YXIgbm9FeGl0UnVudGltZT10cnVlO3ZhciByZWdpc3RlclRMU0luaXQ9dGxzSW5pdEZ1bmM9PlBUaHJlYWQudGxzSW5pdEZ1bmN0aW9ucy5wdXNoKHRsc0luaXRGdW5jKTtmdW5jdGlvbiBwdGhyZWFkQ3JlYXRlUHJveGllZChwdGhyZWFkX3B0cixhdHRyLHN0YXJ0Um91dGluZSxhcmcpe2lmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpcmV0dXJuIHByb3h5VG9NYWluVGhyZWFkKDIsMCwxLHB0aHJlYWRfcHRyLGF0dHIsc3RhcnRSb3V0aW5lLGFyZyk7cmV0dXJuIF9fX3B0aHJlYWRfY3JlYXRlX2pzKHB0aHJlYWRfcHRyLGF0dHIsc3RhcnRSb3V0aW5lLGFyZyl9dmFyIF9lbXNjcmlwdGVuX2hhc190aHJlYWRpbmdfc3VwcG9ydD0oKT0+dHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIjtmdW5jdGlvbiBfX19wdGhyZWFkX2NyZWF0ZV9qcyhwdGhyZWFkX3B0cixhdHRyLHN0YXJ0Um91dGluZSxhcmcpe3B0aHJlYWRfcHRyPj4+PTA7YXR0cj4+Pj0wO3N0YXJ0Um91dGluZT4+Pj0wO2FyZz4+Pj0wO2lmKCFfZW1zY3JpcHRlbl9oYXNfdGhyZWFkaW5nX3N1cHBvcnQoKSl7cmV0dXJuIDZ9dmFyIHRyYW5zZmVyTGlzdD1bXTt2YXIgZXJyb3I9MDtpZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEJiYodHJhbnNmZXJMaXN0Lmxlbmd0aD09PTB8fGVycm9yKSl7cmV0dXJuIHB0aHJlYWRDcmVhdGVQcm94aWVkKHB0aHJlYWRfcHRyLGF0dHIsc3RhcnRSb3V0aW5lLGFyZyl9aWYoZXJyb3IpcmV0dXJuIGVycm9yO3ZhciB0aHJlYWRQYXJhbXM9e3N0YXJ0Um91dGluZSxwdGhyZWFkX3B0cixhcmcsdHJhbnNmZXJMaXN0fTtpZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt0aHJlYWRQYXJhbXMuY21kPSJzcGF3blRocmVhZCI7cG9zdE1lc3NhZ2UodGhyZWFkUGFyYW1zLHRyYW5zZmVyTGlzdCk7cmV0dXJuIDB9cmV0dXJuIHNwYXduVGhyZWFkKHRocmVhZFBhcmFtcyl9ZnVuY3Rpb24gX19lbXNjcmlwdGVuX2luaXRfbWFpbl90aHJlYWRfanModGIpe3RiPj4+PTA7X19lbXNjcmlwdGVuX3RocmVhZF9pbml0KHRiLCFFTlZJUk9OTUVOVF9JU19XT1JLRVIsMSwhRU5WSVJPTk1FTlRfSVNfV0VCLDY1NTM2LGZhbHNlKTtQVGhyZWFkLnRocmVhZEluaXRUTFMoKX12YXIgaGFuZGxlRXhjZXB0aW9uPWU9PntpZihlIGluc3RhbmNlb2YgRXhpdFN0YXR1c3x8ZT09InVud2luZCIpe3JldHVybiBFWElUU1RBVFVTfXF1aXRfKDEsZSl9O3ZhciBtYXliZUV4aXQ9KCk9PntpZigha2VlcFJ1bnRpbWVBbGl2ZSgpKXt0cnl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7aWYoX3B0aHJlYWRfc2VsZigpKV9fZW1zY3JpcHRlbl90aHJlYWRfZXhpdChFWElUU1RBVFVTKTtyZXR1cm59X2V4aXQoRVhJVFNUQVRVUyl9Y2F0Y2goZSl7aGFuZGxlRXhjZXB0aW9uKGUpfX19O3ZhciBjYWxsVXNlckNhbGxiYWNrPWZ1bmM9PntpZihBQk9SVCl7cmV0dXJufXRyeXtmdW5jKCk7bWF5YmVFeGl0KCl9Y2F0Y2goZSl7aGFuZGxlRXhjZXB0aW9uKGUpfX07ZnVuY3Rpb24gX19lbXNjcmlwdGVuX3RocmVhZF9tYWlsYm94X2F3YWl0KHB0aHJlYWRfcHRyKXtwdGhyZWFkX3B0cj4+Pj0wO2lmKHR5cGVvZiBBdG9taWNzLndhaXRBc3luYz09PSJmdW5jdGlvbiIpe3ZhciB3YWl0PUF0b21pY3Mud2FpdEFzeW5jKChncm93TWVtVmlld3MoKSxIRUFQMzIpLHB0aHJlYWRfcHRyPj4+MixwdGhyZWFkX3B0cik7d2FpdC52YWx1ZS50aGVuKGNoZWNrTWFpbGJveCk7dmFyIHdhaXRpbmdBc3luYz1wdGhyZWFkX3B0cisxMjg7QXRvbWljcy5zdG9yZSgoZ3Jvd01lbVZpZXdzKCksSEVBUDMyKSx3YWl0aW5nQXN5bmM+Pj4yLDEpfX12YXIgY2hlY2tNYWlsYm94PSgpPT5jYWxsVXNlckNhbGxiYWNrKCgpPT57dmFyIHB0aHJlYWRfcHRyPV9wdGhyZWFkX3NlbGYoKTtpZihwdGhyZWFkX3B0cil7X19lbXNjcmlwdGVuX3RocmVhZF9tYWlsYm94X2F3YWl0KHB0aHJlYWRfcHRyKTtfX2Vtc2NyaXB0ZW5fY2hlY2tfbWFpbGJveCgpfX0pO2Z1bmN0aW9uIF9fZW1zY3JpcHRlbl9ub3RpZnlfbWFpbGJveF9wb3N0bWVzc2FnZSh0YXJnZXRUaHJlYWQsY3VyclRocmVhZElkKXt0YXJnZXRUaHJlYWQ+Pj49MDtjdXJyVGhyZWFkSWQ+Pj49MDtpZih0YXJnZXRUaHJlYWQ9PWN1cnJUaHJlYWRJZCl7c2V0VGltZW91dChjaGVja01haWxib3gpfWVsc2UgaWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7cG9zdE1lc3NhZ2Uoe3RhcmdldFRocmVhZCxjbWQ6ImNoZWNrTWFpbGJveCJ9KX1lbHNle3ZhciB3b3JrZXI9UFRocmVhZC5wdGhyZWFkc1t0YXJnZXRUaHJlYWRdO2lmKCF3b3JrZXIpe3JldHVybn13b3JrZXIucG9zdE1lc3NhZ2Uoe2NtZDoiY2hlY2tNYWlsYm94In0pfX12YXIgcHJveGllZEpTQ2FsbEFyZ3M9W107ZnVuY3Rpb24gX19lbXNjcmlwdGVuX3JlY2VpdmVfb25fbWFpbl90aHJlYWRfanMoZnVuY0luZGV4LGVtQXNtQWRkcixjYWxsaW5nVGhyZWFkLG51bUNhbGxBcmdzLGFyZ3Mpe2VtQXNtQWRkcj4+Pj0wO2NhbGxpbmdUaHJlYWQ+Pj49MDthcmdzPj4+PTA7bnVtQ2FsbEFyZ3MvPTI7cHJveGllZEpTQ2FsbEFyZ3MubGVuZ3RoPW51bUNhbGxBcmdzO3ZhciBiPWFyZ3M+Pj4zO2Zvcih2YXIgaT0wO2k8bnVtQ2FsbEFyZ3M7aSsrKXtpZigoZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaT4+PjBdKXtwcm94aWVkSlNDYWxsQXJnc1tpXT0oZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaSsxPj4+MF19ZWxzZXtwcm94aWVkSlNDYWxsQXJnc1tpXT0oZ3Jvd01lbVZpZXdzKCksSEVBUEY2NClbYisyKmkrMT4+PjBdfX12YXIgZnVuYz1wcm94aWVkRnVuY3Rpb25UYWJsZVtmdW5jSW5kZXhdO1BUaHJlYWQuY3VycmVudFByb3hpZWRPcGVyYXRpb25DYWxsZXJUaHJlYWQ9Y2FsbGluZ1RocmVhZDt2YXIgcnRuPWZ1bmMoLi4ucHJveGllZEpTQ2FsbEFyZ3MpO1BUaHJlYWQuY3VycmVudFByb3hpZWRPcGVyYXRpb25DYWxsZXJUaHJlYWQ9MDtyZXR1cm4gcnRufWZ1bmN0aW9uIF9fZW1zY3JpcHRlbl90aHJlYWRfY2xlYW51cCh0aHJlYWQpe3RocmVhZD4+Pj0wO2lmKCFFTlZJUk9OTUVOVF9JU19QVEhSRUFEKWNsZWFudXBUaHJlYWQodGhyZWFkKTtlbHNlIHBvc3RNZXNzYWdlKHtjbWQ6ImNsZWFudXBUaHJlYWQiLHRocmVhZH0pfWZ1bmN0aW9uIF9fZW1zY3JpcHRlbl90aHJlYWRfc2V0X3N0cm9uZ3JlZih0aHJlYWQpe3RocmVhZD4+Pj0wO2lmKEVOVklST05NRU5UX0lTX05PREUpe1BUaHJlYWQucHRocmVhZHNbdGhyZWFkXS5yZWYoKX19dmFyIF9lbXNjcmlwdGVuX2dldF9ub3c9KCk9PnBlcmZvcm1hbmNlLnRpbWVPcmlnaW4rcGVyZm9ybWFuY2Uubm93KCk7dmFyIF9lbXNjcmlwdGVuX2NoZWNrX2Jsb2NraW5nX2FsbG93ZWQ9KCk9Pnt9O3ZhciBydW50aW1lS2VlcGFsaXZlUHVzaD0oKT0+e3J1bnRpbWVLZWVwYWxpdmVDb3VudGVyKz0xfTt2YXIgX2Vtc2NyaXB0ZW5fZXhpdF93aXRoX2xpdmVfcnVudGltZT0oKT0+e3J1bnRpbWVLZWVwYWxpdmVQdXNoKCk7dGhyb3cidW53aW5kIn07dmFyIGdldEhlYXBNYXg9KCk9PjQyOTQ5MDE3NjA7dmFyIGFsaWduTWVtb3J5PShzaXplLGFsaWdubWVudCk9Pk1hdGguY2VpbChzaXplL2FsaWdubWVudCkqYWxpZ25tZW50O3ZhciBncm93TWVtb3J5PXNpemU9Pnt2YXIgb2xkSGVhcFNpemU9d2FzbU1lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aDt2YXIgcGFnZXM9KHNpemUtb2xkSGVhcFNpemUrNjU1MzUpLzY1NTM2fDA7dHJ5e3dhc21NZW1vcnkuZ3JvdyhwYWdlcyk7dXBkYXRlTWVtb3J5Vmlld3MoKTtyZXR1cm4gMX1jYXRjaChlKXt9fTtmdW5jdGlvbiBfZW1zY3JpcHRlbl9yZXNpemVfaGVhcChyZXF1ZXN0ZWRTaXplKXtyZXF1ZXN0ZWRTaXplPj4+PTA7dmFyIG9sZFNpemU9KGdyb3dNZW1WaWV3cygpLEhFQVBVOCkubGVuZ3RoO2lmKHJlcXVlc3RlZFNpemU8PW9sZFNpemUpe3JldHVybiBmYWxzZX12YXIgbWF4SGVhcFNpemU9Z2V0SGVhcE1heCgpO2lmKHJlcXVlc3RlZFNpemU+bWF4SGVhcFNpemUpe3JldHVybiBmYWxzZX1mb3IodmFyIGN1dERvd249MTtjdXREb3duPD00O2N1dERvd24qPTIpe3ZhciBvdmVyR3Jvd25IZWFwU2l6ZT1vbGRTaXplKigxKy4yL2N1dERvd24pO292ZXJHcm93bkhlYXBTaXplPU1hdGgubWluKG92ZXJHcm93bkhlYXBTaXplLHJlcXVlc3RlZFNpemUrMTAwNjYzMjk2KTt2YXIgbmV3U2l6ZT1NYXRoLm1pbihtYXhIZWFwU2l6ZSxhbGlnbk1lbW9yeShNYXRoLm1heChyZXF1ZXN0ZWRTaXplLG92ZXJHcm93bkhlYXBTaXplKSw2NTUzNikpO3ZhciByZXBsYWNlbWVudD1ncm93TWVtb3J5KG5ld1NpemUpO2lmKHJlcGxhY2VtZW50KXtyZXR1cm4gdHJ1ZX19cmV0dXJuIGZhbHNlfXZhciBwcmludENoYXJCdWZmZXJzPVtudWxsLFtdLFtdXTt2YXIgVVRGOERlY29kZXI9dHlwZW9mIFRleHREZWNvZGVyIT0idW5kZWZpbmVkIj9uZXcgVGV4dERlY29kZXI6dW5kZWZpbmVkO3ZhciBmaW5kU3RyaW5nRW5kPShoZWFwT3JBcnJheSxpZHgsbWF4Qnl0ZXNUb1JlYWQsaWdub3JlTnVsKT0+e3ZhciBtYXhJZHg9aWR4K21heEJ5dGVzVG9SZWFkO2lmKGlnbm9yZU51bClyZXR1cm4gbWF4SWR4O3doaWxlKGhlYXBPckFycmF5W2lkeF0mJiEoaWR4Pj1tYXhJZHgpKSsraWR4O3JldHVybiBpZHh9O3ZhciBVVEY4QXJyYXlUb1N0cmluZz0oaGVhcE9yQXJyYXksaWR4PTAsbWF4Qnl0ZXNUb1JlYWQsaWdub3JlTnVsKT0+e2lkeD4+Pj0wO3ZhciBlbmRQdHI9ZmluZFN0cmluZ0VuZChoZWFwT3JBcnJheSxpZHgsbWF4Qnl0ZXNUb1JlYWQsaWdub3JlTnVsKTtpZihlbmRQdHItaWR4PjE2JiZoZWFwT3JBcnJheS5idWZmZXImJlVURjhEZWNvZGVyKXtyZXR1cm4gVVRGOERlY29kZXIuZGVjb2RlKGhlYXBPckFycmF5LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyP2hlYXBPckFycmF5LnN1YmFycmF5KGlkeCxlbmRQdHIpOmhlYXBPckFycmF5LnNsaWNlKGlkeCxlbmRQdHIpKX12YXIgc3RyPSIiO3doaWxlKGlkeDxlbmRQdHIpe3ZhciB1MD1oZWFwT3JBcnJheVtpZHgrK107aWYoISh1MCYxMjgpKXtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUodTApO2NvbnRpbnVlfXZhciB1MT1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjIyNCk9PTE5Mil7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKCh1MCYzMSk8PDZ8dTEpO2NvbnRpbnVlfXZhciB1Mj1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjI0MCk9PTIyNCl7dTA9KHUwJjE1KTw8MTJ8dTE8PDZ8dTJ9ZWxzZXt1MD0odTAmNyk8PDE4fHUxPDwxMnx1Mjw8NnxoZWFwT3JBcnJheVtpZHgrK10mNjN9aWYodTA8NjU1MzYpe3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSh1MCl9ZWxzZXt2YXIgY2g9dTAtNjU1MzY7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGNoPj4xMCw1NjMyMHxjaCYxMDIzKX19cmV0dXJuIHN0cn07dmFyIHByaW50Q2hhcj0oc3RyZWFtLGN1cnIpPT57dmFyIGJ1ZmZlcj1wcmludENoYXJCdWZmZXJzW3N0cmVhbV07aWYoY3Vycj09PTB8fGN1cnI9PT0xMCl7KHN0cmVhbT09PTE/b3V0OmVycikoVVRGOEFycmF5VG9TdHJpbmcoYnVmZmVyKSk7YnVmZmVyLmxlbmd0aD0wfWVsc2V7YnVmZmVyLnB1c2goY3Vycil9fTtmdW5jdGlvbiBfZmRfd3JpdGUoZmQsaW92LGlvdmNudCxwbnVtKXtpZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXJldHVybiBwcm94eVRvTWFpblRocmVhZCgzLDAsMSxmZCxpb3YsaW92Y250LHBudW0pO2lvdj4+Pj0wO2lvdmNudD4+Pj0wO3BudW0+Pj49MDt2YXIgbnVtPTA7Zm9yKHZhciBpPTA7aTxpb3ZjbnQ7aSsrKXt2YXIgcHRyPShncm93TWVtVmlld3MoKSxIRUFQVTMyKVtpb3Y+Pj4yPj4+MF07dmFyIGxlbj0oZ3Jvd01lbVZpZXdzKCksSEVBUFUzMilbaW92KzQ+Pj4yPj4+MF07aW92Kz04O2Zvcih2YXIgaj0wO2o8bGVuO2orKyl7cHJpbnRDaGFyKGZkLChncm93TWVtVmlld3MoKSxIRUFQVTgpW3B0citqPj4+MF0pfW51bSs9bGVufShncm93TWVtVmlld3MoKSxIRUFQVTMyKVtwbnVtPj4+Mj4+PjBdPW51bTtyZXR1cm4gMH1QVGhyZWFkLmluaXQoKTt7aW5pdE1lbW9yeSgpO2lmKE1vZHVsZVsibm9FeGl0UnVudGltZSJdKW5vRXhpdFJ1bnRpbWU9TW9kdWxlWyJub0V4aXRSdW50aW1lIl07aWYoTW9kdWxlWyJwcmludCJdKW91dD1Nb2R1bGVbInByaW50Il07aWYoTW9kdWxlWyJwcmludEVyciJdKWVycj1Nb2R1bGVbInByaW50RXJyIl07aWYoTW9kdWxlWyJ3YXNtQmluYXJ5Il0pd2FzbUJpbmFyeT1Nb2R1bGVbIndhc21CaW5hcnkiXTtpZihNb2R1bGVbImFyZ3VtZW50cyJdKWFyZ3VtZW50c189TW9kdWxlWyJhcmd1bWVudHMiXTtpZihNb2R1bGVbInRoaXNQcm9ncmFtIl0pdGhpc1Byb2dyYW09TW9kdWxlWyJ0aGlzUHJvZ3JhbSJdO2lmKE1vZHVsZVsicHJlSW5pdCJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVJbml0Il09PSJmdW5jdGlvbiIpTW9kdWxlWyJwcmVJbml0Il09W01vZHVsZVsicHJlSW5pdCJdXTt3aGlsZShNb2R1bGVbInByZUluaXQiXS5sZW5ndGg+MCl7TW9kdWxlWyJwcmVJbml0Il0uc2hpZnQoKSgpfX19TW9kdWxlWyJ3YXNtTWVtb3J5Il09d2FzbU1lbW9yeTt2YXIgcHJveGllZEZ1bmN0aW9uVGFibGU9W19wcm9jX2V4aXQsZXhpdE9uTWFpblRocmVhZCxwdGhyZWFkQ3JlYXRlUHJveGllZCxfZmRfd3JpdGVdO3ZhciBfc2thaW5ldF9mcDMyX21hdG11bCxfc2thaW5ldF9mcDMyX21hdG11bF93dCxfc2thaW5ldF9iZjE2X21hdG11bCxfc2thaW5ldF9mcDE2X21hdG11bCxfc2thaW5ldF9xNF8wX21hdG11bCxfc2thaW5ldF9xNF8wX21hdG11bF9ybSxfc2thaW5ldF9xNV8wX21hdG11bCxfbWFsbG9jLF9mcmVlLF9za2FpbmV0X3E1XzBfbWF0bXVsX3JtLF9za2FpbmV0X3E1XzFfbWF0bXVsLF9za2FpbmV0X3E1XzFfbWF0bXVsX3JtLF9za2FpbmV0X3E4XzBfbWF0bXVsLF9za2FpbmV0X3E4XzBfbWF0bXVsX3JtLF9za2FpbmV0X3E0a19tYXRtdWwsX3NrYWluZXRfcTRrX21hdG11bF9ybSxfc2thaW5ldF9xNWtfbWF0bXVsLF9za2FpbmV0X3E1a19tYXRtdWxfcm0sX3NrYWluZXRfcTZrX21hdG11bCxfc2thaW5ldF9xNmtfbWF0bXVsX3JtLF9fZW1zY3JpcHRlbl90bHNfaW5pdCxfcHRocmVhZF9zZWxmLF9fZW1zY3JpcHRlbl90aHJlYWRfaW5pdCxfX2Vtc2NyaXB0ZW5fdGhyZWFkX2NyYXNoZWQsX19lbXNjcmlwdGVuX3J1bl9qc19vbl9tYWluX3RocmVhZCxfX2Vtc2NyaXB0ZW5fdGhyZWFkX2ZyZWVfZGF0YSxfX2Vtc2NyaXB0ZW5fdGhyZWFkX2V4aXQsX19lbXNjcmlwdGVuX2NoZWNrX21haWxib3gsX2Vtc2NyaXB0ZW5fc3RhY2tfc2V0X2xpbWl0cyxfX2Vtc2NyaXB0ZW5fc3RhY2tfcmVzdG9yZSxfX2Vtc2NyaXB0ZW5fc3RhY2tfYWxsb2MsX2Vtc2NyaXB0ZW5fc3RhY2tfZ2V0X2N1cnJlbnQ7ZnVuY3Rpb24gYXNzaWduV2FzbUV4cG9ydHMod2FzbUV4cG9ydHMpe01vZHVsZVsiX3NrYWluZXRfZnAzMl9tYXRtdWwiXT1fc2thaW5ldF9mcDMyX21hdG11bD13YXNtRXhwb3J0c1sicCJdO01vZHVsZVsiX3NrYWluZXRfZnAzMl9tYXRtdWxfd3QiXT1fc2thaW5ldF9mcDMyX21hdG11bF93dD13YXNtRXhwb3J0c1sicSJdO01vZHVsZVsiX3NrYWluZXRfYmYxNl9tYXRtdWwiXT1fc2thaW5ldF9iZjE2X21hdG11bD13YXNtRXhwb3J0c1sicyJdO01vZHVsZVsiX3NrYWluZXRfZnAxNl9tYXRtdWwiXT1fc2thaW5ldF9mcDE2X21hdG11bD13YXNtRXhwb3J0c1sidCJdO01vZHVsZVsiX3NrYWluZXRfcTRfMF9tYXRtdWwiXT1fc2thaW5ldF9xNF8wX21hdG11bD13YXNtRXhwb3J0c1sidSJdO01vZHVsZVsiX3NrYWluZXRfcTRfMF9tYXRtdWxfcm0iXT1fc2thaW5ldF9xNF8wX21hdG11bF9ybT13YXNtRXhwb3J0c1sidiJdO01vZHVsZVsiX3NrYWluZXRfcTVfMF9tYXRtdWwiXT1fc2thaW5ldF9xNV8wX21hdG11bD13YXNtRXhwb3J0c1sidyJdO01vZHVsZVsiX21hbGxvYyJdPV9tYWxsb2M9d2FzbUV4cG9ydHNbIngiXTtNb2R1bGVbIl9mcmVlIl09X2ZyZWU9d2FzbUV4cG9ydHNbInkiXTtNb2R1bGVbIl9za2FpbmV0X3E1XzBfbWF0bXVsX3JtIl09X3NrYWluZXRfcTVfMF9tYXRtdWxfcm09d2FzbUV4cG9ydHNbInoiXTtNb2R1bGVbIl9za2FpbmV0X3E1XzFfbWF0bXVsIl09X3NrYWluZXRfcTVfMV9tYXRtdWw9d2FzbUV4cG9ydHNbIkEiXTtNb2R1bGVbIl9za2FpbmV0X3E1XzFfbWF0bXVsX3JtIl09X3NrYWluZXRfcTVfMV9tYXRtdWxfcm09d2FzbUV4cG9ydHNbIkIiXTtNb2R1bGVbIl9za2FpbmV0X3E4XzBfbWF0bXVsIl09X3NrYWluZXRfcThfMF9tYXRtdWw9d2FzbUV4cG9ydHNbIkMiXTtNb2R1bGVbIl9za2FpbmV0X3E4XzBfbWF0bXVsX3JtIl09X3NrYWluZXRfcThfMF9tYXRtdWxfcm09d2FzbUV4cG9ydHNbIkQiXTtNb2R1bGVbIl9za2FpbmV0X3E0a19tYXRtdWwiXT1fc2thaW5ldF9xNGtfbWF0bXVsPXdhc21FeHBvcnRzWyJFIl07TW9kdWxlWyJfc2thaW5ldF9xNGtfbWF0bXVsX3JtIl09X3NrYWluZXRfcTRrX21hdG11bF9ybT13YXNtRXhwb3J0c1siRiJdO01vZHVsZVsiX3NrYWluZXRfcTVrX21hdG11bCJdPV9za2FpbmV0X3E1a19tYXRtdWw9d2FzbUV4cG9ydHNbIkciXTtNb2R1bGVbIl9za2FpbmV0X3E1a19tYXRtdWxfcm0iXT1fc2thaW5ldF9xNWtfbWF0bXVsX3JtPXdhc21FeHBvcnRzWyJIIl07TW9kdWxlWyJfc2thaW5ldF9xNmtfbWF0bXVsIl09X3NrYWluZXRfcTZrX21hdG11bD13YXNtRXhwb3J0c1siSSJdO01vZHVsZVsiX3NrYWluZXRfcTZrX21hdG11bF9ybSJdPV9za2FpbmV0X3E2a19tYXRtdWxfcm09d2FzbUV4cG9ydHNbIkoiXTtfX2Vtc2NyaXB0ZW5fdGxzX2luaXQ9d2FzbUV4cG9ydHNbIksiXTtfcHRocmVhZF9zZWxmPXdhc21FeHBvcnRzWyJMIl07X19lbXNjcmlwdGVuX3RocmVhZF9pbml0PXdhc21FeHBvcnRzWyJNIl07X19lbXNjcmlwdGVuX3RocmVhZF9jcmFzaGVkPXdhc21FeHBvcnRzWyJOIl07X19lbXNjcmlwdGVuX3J1bl9qc19vbl9tYWluX3RocmVhZD13YXNtRXhwb3J0c1siTyJdO19fZW1zY3JpcHRlbl90aHJlYWRfZnJlZV9kYXRhPXdhc21FeHBvcnRzWyJQIl07X19lbXNjcmlwdGVuX3RocmVhZF9leGl0PXdhc21FeHBvcnRzWyJRIl07X19lbXNjcmlwdGVuX2NoZWNrX21haWxib3g9d2FzbUV4cG9ydHNbIlIiXTtfZW1zY3JpcHRlbl9zdGFja19zZXRfbGltaXRzPXdhc21FeHBvcnRzWyJTIl07X19lbXNjcmlwdGVuX3N0YWNrX3Jlc3RvcmU9d2FzbUV4cG9ydHNbIlQiXTtfX2Vtc2NyaXB0ZW5fc3RhY2tfYWxsb2M9d2FzbUV4cG9ydHNbIlUiXTtfZW1zY3JpcHRlbl9zdGFja19nZXRfY3VycmVudD13YXNtRXhwb3J0c1siViJdfXZhciB3YXNtSW1wb3J0cztmdW5jdGlvbiBhc3NpZ25XYXNtSW1wb3J0cygpe3dhc21JbXBvcnRzPXtnOl9fX3B0aHJlYWRfY3JlYXRlX2pzLGs6X19lbXNjcmlwdGVuX2luaXRfbWFpbl90aHJlYWRfanMsbjpfX2Vtc2NyaXB0ZW5fbm90aWZ5X21haWxib3hfcG9zdG1lc3NhZ2UsbDpfX2Vtc2NyaXB0ZW5fcmVjZWl2ZV9vbl9tYWluX3RocmVhZF9qcyxjOl9fZW1zY3JpcHRlbl90aHJlYWRfY2xlYW51cCxqOl9fZW1zY3JpcHRlbl90aHJlYWRfbWFpbGJveF9hd2FpdCxpOl9fZW1zY3JpcHRlbl90aHJlYWRfc2V0X3N0cm9uZ3JlZixlOl9lbXNjcmlwdGVuX2NoZWNrX2Jsb2NraW5nX2FsbG93ZWQsaDpfZW1zY3JpcHRlbl9leGl0X3dpdGhfbGl2ZV9ydW50aW1lLGI6X2Vtc2NyaXB0ZW5fZ2V0X25vdyxtOl9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwLGY6X2V4aXQsZDpfZmRfd3JpdGUsYTp3YXNtTWVtb3J5fX1mdW5jdGlvbiBhcHBseVNpZ25hdHVyZUNvbnZlcnNpb25zKHdhc21FeHBvcnRzKXt3YXNtRXhwb3J0cz1PYmplY3QuYXNzaWduKHt9LHdhc21FeHBvcnRzKTt2YXIgbWFrZVdyYXBwZXJfcHA9Zj0+YTA9PmYoYTApPj4+MDt2YXIgbWFrZVdyYXBwZXJfcD1mPT4oKT0+ZigpPj4+MDt3YXNtRXhwb3J0c1sieCJdPW1ha2VXcmFwcGVyX3BwKHdhc21FeHBvcnRzWyJ4Il0pO3dhc21FeHBvcnRzWyJMIl09bWFrZVdyYXBwZXJfcCh3YXNtRXhwb3J0c1siTCJdKTt3YXNtRXhwb3J0c1siVSJdPW1ha2VXcmFwcGVyX3BwKHdhc21FeHBvcnRzWyJVIl0pO3dhc21FeHBvcnRzWyJWIl09bWFrZVdyYXBwZXJfcCh3YXNtRXhwb3J0c1siViJdKTtyZXR1cm4gd2FzbUV4cG9ydHN9ZnVuY3Rpb24gcnVuKCl7aWYocnVuRGVwZW5kZW5jaWVzPjApe2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1ydW47cmV0dXJufWlmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpe3JlYWR5UHJvbWlzZVJlc29sdmU/LihNb2R1bGUpO2luaXRSdW50aW1lKCk7cmV0dXJufXByZVJ1bigpO2lmKHJ1bkRlcGVuZGVuY2llcz4wKXtkZXBlbmRlbmNpZXNGdWxmaWxsZWQ9cnVuO3JldHVybn1mdW5jdGlvbiBkb1J1bigpe01vZHVsZVsiY2FsbGVkUnVuIl09dHJ1ZTtpZihBQk9SVClyZXR1cm47aW5pdFJ1bnRpbWUoKTtyZWFkeVByb21pc2VSZXNvbHZlPy4oTW9kdWxlKTtNb2R1bGVbIm9uUnVudGltZUluaXRpYWxpemVkIl0/LigpO3Bvc3RSdW4oKX1pZihNb2R1bGVbInNldFN0YXR1cyJdKXtNb2R1bGVbInNldFN0YXR1cyJdKCJSdW5uaW5nLi4uIik7c2V0VGltZW91dCgoKT0+e3NldFRpbWVvdXQoKCk9Pk1vZHVsZVsic2V0U3RhdHVzIl0oIiIpLDEpO2RvUnVuKCl9LDEpfWVsc2V7ZG9SdW4oKX19dmFyIHdhc21FeHBvcnRzO2lmKCFFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt3YXNtRXhwb3J0cz1hd2FpdCAoY3JlYXRlV2FzbSgpKTtydW4oKX1pZihydW50aW1lSW5pdGlhbGl6ZWQpe21vZHVsZVJ0bj1Nb2R1bGV9ZWxzZXttb2R1bGVSdG49bmV3IFByb21pc2UoKHJlc29sdmUscmVqZWN0KT0+e3JlYWR5UHJvbWlzZVJlc29sdmU9cmVzb2x2ZTtyZWFkeVByb21pc2VSZWplY3Q9cmVqZWN0fSl9CjtyZXR1cm4gbW9kdWxlUnRufWV4cG9ydCBkZWZhdWx0IGNyZWF0ZVNrYWluZXRLZXJuZWxzO3ZhciBpc1B0aHJlYWQ9Z2xvYmFsVGhpcy5zZWxmPy5uYW1lPy5zdGFydHNXaXRoKCJlbS1wdGhyZWFkIik7dmFyIGlzTm9kZT10eXBlb2YgcHJvY2Vzcz09Im9iamVjdCImJnByb2Nlc3MudmVyc2lvbnM/Lm5vZGUmJnByb2Nlc3MudHlwZSE9InJlbmRlcmVyIjtpZihpc05vZGUpaXNQdGhyZWFkPShhd2FpdCBpbXBvcnQoIndvcmtlcl90aHJlYWRzIikpLndvcmtlckRhdGE9PT0iZW0tcHRocmVhZCI7aXNQdGhyZWFkJiZjcmVhdGVTa2FpbmV0S2VybmVscygpOwo=" - const val MT_WASM: String = "AGFzbQEAAAABkAEUYAF/AGADf39/AGAAAGAIf39/f39/f38AYAJ/fwBgAX8Bf2ACf38Bf2AAAX9gCX9/f39/f39/fwBgDH9/f39/f39/f39/fwBgBH9/f38Bf2AFf39/f38BfGADf39/AX9gAAF8YAN/f3wBf2AEf399fwF9YAJ/fwF9YAN/f30BfWAGf39/f39/AGADf35/AX4CWg4BYQFiAA0BYQFjAAABYQFkAAoBYQFlAAIBYQFmAAABYQFnAAoBYQFoAAIBYQFpAAABYQFqAAABYQFrAAABYQFsAAsBYQFtAAUBYQFuAAQBYQFhAgOACICABAN0cwAFBAAFAQEFDgABBAUAAAYMCAgCBwAFAgIEBgAAAgQAAgQEAgAAAAYGBgAEAAUPEBEEAgAHAAMAAAABAgADAAsEAAIAAAkAAAkHBQIBAQMBAwEDAQMIAQMBAwEDAQMJAQMBAwEDAQcFABIEAxMMBQIBAgIEBQFwASIiBjUKfwFBkKIEC38BQQALfwFBAAt/AUEAC38BQQALfwFBAAt/AUEAC38BQQALfwFBAAt/AUEACweJASIBbwB/AXAAawFxAGIBcgEAAXMAVQF0AFIBdQBKAXYAQwF3AHgBeAARAXkAEAF6AHEBQQBvAUIAbQFDAGoBRABoAUUAZgFGAGQBRwBhAUgAXwFJAF0BSgBbAUsAVgFMAEEBTQB2AU4ASAFPAEwBUABGAVEARQFSAHwBUwB3AVQAdQFVAHQBVgBzCAF+CScBAEEBCyFZR31ycG5saWdlY2BeXFpYV1RTFlExUE9OSU1LREJ7enkMAQIK+oIDc/MBAQd/IAAoAgghBAJAAkAgACgCACICQQ9xRQRAIABBBGoiAUEA/kECACEADAELIwMiAygCGCAAKAIEIgVB/////wNxRw0BAkAgAkEDcUEBRw0AIAAoAhQiAUUNACAAIAFBAWs2AhQPCyACQYABcSIGBEAgAyAAQRBqNgJUQQBBAf4eApQNGgsgAEEEaiEBIAAoAgwiByAAKAIQIgA2AgAgA0HMAGogAEcEQCAAQQRrIAc2AgALIAEgBUEBdCACQR10cUEfdUH/////B3H+QQIAIQAgBkUNACADQQA2AlQQLQsgBEUgAEEATnENACABQQEQDwsLqAIBBn8CQCAALQAAQQ9xDQAgAEEEakEAQQr+SAIADQBBAA8LAn8CQCAAKAIAIgJBD3FFBEAgAEEEakEAQQr+SAIARQ0BIAAoAgAhAgsgABAZIgFBCkcNACAAQQhqIQQgAEEEaiEDQeQAIQEDQAJAIAFFDQAgAygCAEUNACABQQFrIQEgBCgCAEUNAQsLIAAQGSIBQQpHDQAgAkEEcUUhBSACQQNxQQJHIQIDQAJAIAMoAgAiAUH/////A3EiBiABQQBHIAVxckUNAAJAIAINACAGIwMoAhhHDQBBEAwECyAEQQH+HgIAGiADIAEgAUGAgICAeHIiAf5IAgAaIAMgARAnIQEgBEEB/iUCABogAUEbRg0AIAENAgsgABAZIgFBCkYNAAsLIAELC2QBAX8CQCAARQ0AIAFBAEgNACAAQQNxDQAgAUUEQA8LIABBACAAQQD+SAKYCyICIAAgAkYbIQICQCABQf////8HRg0AIAAgAkcNACABQQFGDQEgAUEBayEBCyAAIAH+AAIAGgsLiwwBCH8CQCAARQ0AQbQZLQAAQQJxBEBBuBkQDg0BCyAAQQhrIgMgAEEEaygCACICQXhxIgBqIQUCQAJAIAJBAXENACACQQJxRQ0BIAMgAygCACIEayIDQYgWKAIASQ0BIAAgBGohAAJAAkACQEGMFigCACADRwRAIAMoAgwhASAEQf8BTQRAIAEgAygCCCICRw0CQfgVQfgVKAIAQX4gBEEDdndxNgIADAULIAMoAhghByABIANHBEAgAygCCCICIAE2AgwgASACNgIIDAQLIAMoAhQiAgR/IANBFGoFIAMoAhAiAkUNAyADQRBqCyEEA0AgBCEGIAIiAUEUaiEEIAEoAhQiAg0AIAFBEGohBCABKAIQIgINAAsgBkEANgIADAMLIAUoAgQiAkEDcUEDRw0DQYAWIAA2AgAgBSACQX5xNgIEIAMgAEEBcjYCBCAFIAA2AgAMBAsgAiABNgIMIAEgAjYCCAwCC0EAIQELIAdFDQACQCADKAIcIgRBAnQiAigCqBggA0YEQCACQagYaiABNgIAIAENAUH8FUH8FSgCAEF+IAR3cTYCAAwCCwJAIAMgBygCEEYEQCAHIAE2AhAMAQsgByABNgIUCyABRQ0BCyABIAc2AhggAygCECICBEAgASACNgIQIAIgATYCGAsgAygCFCICRQ0AIAEgAjYCFCACIAE2AhgLIAMgBU8NACAFKAIEIgRBAXFFDQACQAJAAkACQCAEQQJxRQRAQZAWKAIAIAVGBEBBkBYgAzYCAEGEFkGEFigCACAAaiIANgIAIAMgAEEBcjYCBCADQYwWKAIARw0GQYAWQQA2AgBBjBZBADYCAAwGC0GMFigCACIHIAVGBEBBjBYgAzYCAEGAFkGAFigCACAAaiIANgIAIAMgAEEBcjYCBCAAIANqIAA2AgAMBgsgBEF4cSAAaiEAIAUoAgwhASAEQf8BTQRAIAUoAggiAiABRgRAQfgVQfgVKAIAQX4gBEEDdndxNgIADAULIAIgATYCDCABIAI2AggMBAsgBSgCGCEIIAEgBUcEQCAFKAIIIgIgATYCDCABIAI2AggMAwsgBSgCFCICBH8gBUEUagUgBSgCECICRQ0CIAVBEGoLIQQDQCAEIQYgAiIBQRRqIQQgASgCFCICDQAgAUEQaiEEIAEoAhAiAg0ACyAGQQA2AgAMAgsgBSAEQX5xNgIEIAMgAEEBcjYCBCAAIANqIAA2AgAMAwtBACEBCyAIRQ0AAkAgBSgCHCIEQQJ0IgIoAqgYIAVGBEAgAkGoGGogATYCACABDQFB/BVB/BUoAgBBfiAEd3E2AgAMAgsCQCAFIAgoAhBGBEAgCCABNgIQDAELIAggATYCFAsgAUUNAQsgASAINgIYIAUoAhAiAgRAIAEgAjYCECACIAE2AhgLIAUoAhQiAkUNACABIAI2AhQgAiABNgIYCyADIABBAXI2AgQgACADaiAANgIAIAMgB0cNAEGAFiAANgIADAELIABB/wFNBEAgAEH4AXFBoBZqIQICf0H4FSgCACIEQQEgAEEDdnQiAHFFBEBB+BUgACAEcjYCACACDAELIAIoAggLIQAgAiADNgIIIAAgAzYCDCADIAI2AgwgAyAANgIIDAELQR8hASAAQf///wdNBEAgAEEmIABBCHZnIgJrdkEBcSACQQF0a0E+aiEBCyADIAE2AhwgA0IANwIQIAFBAnRBqBhqIQQCfwJAAn9B/BUoAgAiBkEBIAF0IgJxRQRAQfwVIAIgBnI2AgAgBCADNgIAQRghAUEIDAELIABBGSABQQF2a0EAIAFBH0cbdCEBIAQoAgAhBANAIAQiAigCBEF4cSAARg0CIAFBHXYhBCABQQF0IQEgAiAEQQRxaiIGKAIQIgQNAAsgBiADNgIQQRghASACIQRBCAshACADIgIMAQsgAigCCCIEIAM2AgwgAiADNgIIQRghAEEIIQFBAAshBiABIANqIAQ2AgAgAyACNgIMIAAgA2ogBjYCAEGYFkGYFigCAEEBayIAQX8gABs2AgALQbQZLQAAQQJxRQ0AQbgZEA0LC9InAQl/QeAVKAIARQRAED8LAkBBtBktAABBAnEEQEG4GRAODQELAkACQAJAAkACQAJAAkACQCAAQfQBTQRAQfgVKAIAIgJBECAAQQtqQfgDcSAAQQtJGyIFQQN2IgB2IgFBA3EEQAJAIAFBf3NBAXEgAGoiBEEDdCIAQaAWaiIFIAAoAqgWIgEoAggiA0YEQEH4FSACQX4gBHdxNgIADAELIAMgBTYCDCAFIAM2AggLIAFBCGohBCABIABBA3I2AgQgACABaiIAIAAoAgRBAXI2AgQMCQsgBUGAFigCACIDTQ0BIAEEQAJAQQIgAHQiBEEAIARrciABIAB0cWgiB0EDdCIBQaAWaiIEIAEoAqgWIgAoAggiBkYEQEH4FSACQX4gB3dxIgI2AgAMAQsgBiAENgIMIAQgBjYCCAsgACAFQQNyNgIEIAAgBWoiByABIAVrIgZBAXI2AgQgACABaiAGNgIAIAMEQCADQXhxQaAWaiEBQYwWKAIAIQUCfyACQQEgA0EDdnQiA3FFBEBB+BUgAiADcjYCACABDAELIAEoAggLIQIgASAFNgIIIAIgBTYCDCAFIAE2AgwgBSACNgIICyAAQQhqIQRBjBYgBzYCAEGAFiAGNgIADAkLQfwVKAIAIghFDQEgCGhBAnQoAqgYIgIoAgRBeHEgBWshBiACIQADQAJAIAAoAhAiAUUEQCAAKAIUIgFFDQELIAEoAgRBeHEgBWsiACAGIAAgBkkiABshBiABIAIgABshAiABIQAMAQsLIAIoAhghBwJAIAIgAigCDCIBRwRAIAIoAggiACABNgIMIAEgADYCCAwBCwJAIAIoAhQiAAR/IAJBFGoFIAIoAhAiAEUNASACQRBqCyEDA0AgAyEEIAAiAUEUaiEDIAAoAhQiAA0AIAFBEGohAyABKAIQIgANAAsgBEEANgIADAELQQAhAQsCQCAHRQ0AAkAgAigCHCIAQQJ0IgMoAqgYIAJGBEAgA0GoGGogATYCACABDQFB/BUgCEF+IAB3cTYCAAwCCwJAIAIgBygCEEYEQCAHIAE2AhAMAQsgByABNgIUCyABRQ0BCyABIAc2AhggAigCECIABEAgASAANgIQIAAgATYCGAsgAigCFCIARQ0AIAEgADYCFCAAIAE2AhgLAkAgBkEPTQRAIAIgBSAGaiIAQQNyNgIEIAAgAmoiACAAKAIEQQFyNgIEDAELIAIgBUEDcjYCBCACIAVqIgUgBkEBcjYCBCAFIAZqIAY2AgBBgBYoAgAiAwRAIANBeHFBoBZqIQBBjBYoAgAhAQJ/QfgVKAIAIgRBASADQQN2dCIDcUUEQEH4FSADIARyNgIAIAAMAQsgACgCCAshAyAAIAE2AgggAyABNgIMIAEgADYCDCABIAM2AggLQYwWIAU2AgBBgBYgBjYCAAsgAkEIaiEEDAgLQX8hBSAAQb9/Sw0AIABBC2oiAUF4cSEFQfwVKAIAIgdFDQBBHyEIQQAgBWshBCAAQfT//wdNBEAgBUEmIAFBCHZnIgBrdkEBcSAAQQF0a0E+aiEICwJAAkACQCAIQQJ0KAKoGCIBRQRAQQAhAAwBC0EAIQAgBUEZIAhBAXZrQQAgCEEfRxt0IQIDQAJAIAEoAgRBeHEgBWsiBiAETw0AIAEhAyAGIgQNAEEAIQQgASEADAMLIAAgASgCFCIGIAYgASACQR12QQRxaigCECIBRhsgACAGGyEAIAJBAXQhAiABDQALCyAAIANyRQRAQQAhA0ECIAh0IgBBACAAa3IgB3EiAEUNAyAAaEECdCgCqBghAAsgAEUNAQsDQCAAKAIEQXhxIAVrIgIgBEkhASACIAQgARshBCAAIAMgARshAyAAKAIQIgEEfyABBSAAKAIUCyIADQALCyADRQ0AIARBgBYoAgAgBWtPDQAgAygCGCEIIAMgAygCDCIARwRAIAMoAggiASAANgIMIAAgATYCCAwHCyADKAIUIgEEfyADQRRqBSADKAIQIgFFDQIgA0EQagshAgNAIAIhBiABIgBBFGohAiAAKAIUIgENACAAQRBqIQIgACgCECIBDQALIAZBADYCAAwGCyAFQYAWKAIAIgNNBEBBjBYoAgAhAAJAIAMgBWsiAUEQTwRAIAAgBWoiAiABQQFyNgIEIAAgA2ogATYCACAAIAVBA3I2AgQMAQsgACADQQNyNgIEIAAgA2oiASABKAIEQQFyNgIEQQAhAkEAIQELQYAWIAE2AgBBjBYgAjYCACAAQQhqIQQMBwsgBUGEFigCACIASQRAQYQWIAAgBWsiATYCAEGQFkGQFigCACIAIAVqIgI2AgAgAiABQQFyNgIEIAAgBUEDcjYCBCAAQQhqIQQMBwtBACEEQeAVKAIARQRAED8LQegVKAIAIgAgBUEvaiIGakEAIABrcSIDIAVNDQZBsBkoAgAiAARAQagZKAIAIgEgA2oiAiABTQ0HIAAgAkkNBwtBtBktAABBBHFFBEACQAJAAkACQEGQFigCACIBBEBB0BkhAANAIAAoAgAiAiABTQRAIAEgAiAAKAIEakkNAwsgACgCCCIADQALC0HoGRAOGkEAEBQiAkF/Rg0DIAMhAUHkFSgCACIAQQFrIgQgAnEEQCABIAJrIAIgBGpBACAAa3FqIQELIAEgBU0NA0GwGSgCACIABEBBqBkoAgAiBCABaiIHIARNDQQgACAHSQ0ECyABEBQiACACRw0BDAYLQegZEA4aQegVKAIAIgEgBkGEFigCAGtqQQAgAWtxIgEQFCICIAAoAgAgACgCBGpGDQEgAiEACyAAQX9GDQEgBUEwaiABSwRAQegVKAIAIgIgBiABa2pBACACa3EiAhAUQX9GDQIgASACaiEBCyAAIQIMBAsgAkF/Rw0DC0G0GUG0GSgCAEEEcjYCAEHoGRANC0HoGRAOGiADEBQhAkEAEBQhAEHoGRANIAJBf0YNAyAAQX9GDQMgACACTQ0DIAAgAmsiASAFQShqTQ0DDAILQQAhAAwEC0HoGRANC0GoGUGoGSgCACABaiIANgIAQawZKAIAIABJBEBBrBkgADYCAAsCQAJAAkBBkBYoAgAiBARAQdAZIQADQCACIAAoAgAiAyAAKAIEIgZqRg0CIAAoAggiAA0ACwwCC0GIFigCACIAQQAgACACTRtFBEBBiBYgAjYCAAtBACEAQdQZIAE2AgBB0BkgAjYCAEGYFkF/NgIAQZwWQeAVKAIANgIAQdwZQQA2AgADQCAAQQN0IgMgA0GgFmoiBDYCqBYgAyAENgKsFiAAQQFqIgBBIEcNAAtBhBYgAUEoayIAQXggAmtBB3EiAWsiAzYCAEGQFiABIAJqIgE2AgAgASADQQFyNgIEIAAgAmpBKDYCBEGUFkHwFSgCADYCAAwCCyACIARNDQAgAyAESw0AIAAoAgxBCHENACAAIAEgBmo2AgRBkBYgBEF4IARrQQdxIgBqIgI2AgBBhBZBhBYoAgAgAWoiASAAayIANgIAIAIgAEEBcjYCBCABIARqQSg2AgRBlBZB8BUoAgA2AgAMAQtBiBYoAgAgAksEQEGIFiACNgIACyABIAJqIQZB0BkhAAJAA0AgBiAAKAIAIgNHBEAgACgCCCIADQEMAgsLIAAtAAxBCHFFDQMLQdAZIQADQAJAIAAoAgAiAyAETQRAIAQgAyAAKAIEaiIGSQ0BCyAAKAIIIQAMAQsLQYQWIAFBKGsiAEF4IAJrQQdxIgNrIgc2AgBBkBYgAiADaiIDNgIAIAMgB0EBcjYCBCAAIAJqQSg2AgRBlBZB8BUoAgA2AgAgBCAGQScgBmtBB3FqQS9rIgAgACAEQRBqSRsiA0EbNgIEIANB2BkpAgA3AhAgA0HQGSkCADcCCEHYGSADQQhqNgIAQdQZIAE2AgBB0BkgAjYCAEHcGUEANgIAIANBGGohAANAIABBBzYCBCAAQQhqIABBBGohACAGSQ0ACyADIARGDQAgAyADKAIEQX5xNgIEIAQgAyAEayICQQFyNgIEIAMgAjYCAAJ/IAJB/wFNBEAgAkH4AXFBoBZqIQACf0H4FSgCACIBQQEgAkEDdnQiAnFFBEBB+BUgASACcjYCACAADAELIAAoAggLIQEgACAENgIIIAEgBDYCDEEIIQNBDAwBC0EfIQAgAkH///8HTQRAIAJBJiACQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAAsgBCAANgIcIARCADcCECAAQQJ0QagYaiEBAkACQEH8FSgCACIDQQEgAHQiBnFFBEBB/BUgAyAGcjYCACABIAQ2AgAMAQsgAkEZIABBAXZrQQAgAEEfRxt0IQAgASgCACEDA0AgAyIBKAIEQXhxIAJGDQIgAEEddiEDIABBAXQhACABIANBBHFqIgYoAhAiAw0ACyAGIAQ2AhALIAQgATYCGEEMIQMgBCIBIQBBCAwBCyABKAIIIgAgBDYCDCABIAQ2AgggBCAANgIIQQAhAEEMIQNBGAsgAyAEaiABNgIAIARqIAA2AgALQYQWKAIAIgAgBU0NAEGEFiAAIAVrIgE2AgBBkBZBkBYoAgAiACAFaiICNgIAIAIgAUEBcjYCBCAAIAVBA3I2AgQgAEEIaiEEDAMLIwFBMDYCAEEAIQQMAgsgACACNgIAIAAgACgCBCABajYCBCACQXggAmtBB3FqIgggBUEDcjYCBCADQXggA2tBB3FqIgQgBSAIaiIDayEGAkBBkBYoAgAgBEYEQEGQFiADNgIAQYQWQYQWKAIAIAZqIgA2AgAgAyAAQQFyNgIEDAELQYwWKAIAIARGBEBBjBYgAzYCAEGAFkGAFigCACAGaiIANgIAIAMgAEEBcjYCBCAAIANqIAA2AgAMAQsgBCgCBCIAQQNxQQFGBEAgAEF4cSEJIAQoAgwhAgJAIABB/wFNBEAgBCgCCCIBIAJGBEBB+BVB+BUoAgBBfiAAQQN2d3E2AgAMAgsgASACNgIMIAIgATYCCAwBCyAEKAIYIQcCQCACIARHBEAgBCgCCCIAIAI2AgwgAiAANgIIDAELAkAgBCgCFCIABH8gBEEUagUgBCgCECIARQ0BIARBEGoLIQEDQCABIQUgACICQRRqIQEgACgCFCIADQAgAkEQaiEBIAIoAhAiAA0ACyAFQQA2AgAMAQtBACECCyAHRQ0AAkAgBCgCHCIAQQJ0IgEoAqgYIARGBEAgAUGoGGogAjYCACACDQFB/BVB/BUoAgBBfiAAd3E2AgAMAgsCQCAEIAcoAhBGBEAgByACNgIQDAELIAcgAjYCFAsgAkUNAQsgAiAHNgIYIAQoAhAiAARAIAIgADYCECAAIAI2AhgLIAQoAhQiAEUNACACIAA2AhQgACACNgIYCyAGIAlqIQYgBCAJaiIEKAIEIQALIAQgAEF+cTYCBCADIAZBAXI2AgQgAyAGaiAGNgIAIAZB/wFNBEAgBkH4AXFBoBZqIQACf0H4FSgCACIBQQEgBkEDdnQiAnFFBEBB+BUgASACcjYCACAADAELIAAoAggLIQEgACADNgIIIAEgAzYCDCADIAA2AgwgAyABNgIIDAELQR8hAiAGQf///wdNBEAgBkEmIAZBCHZnIgBrdkEBcSAAQQF0a0E+aiECCyADIAI2AhwgA0IANwIQIAJBAnRBqBhqIQACQAJAQfwVKAIAIgFBASACdCIFcUUEQEH8FSABIAVyNgIAIAAgAzYCAAwBCyAGQRkgAkEBdmtBACACQR9HG3QhAiAAKAIAIQEDQCABIgAoAgRBeHEgBkYNAiACQR12IQEgAkEBdCECIAAgAUEEcWoiBSgCECIBDQALIAUgAzYCEAsgAyAANgIYIAMgAzYCDCADIAM2AggMAQsgACgCCCIBIAM2AgwgACADNgIIIANBADYCGCADIAA2AgwgAyABNgIICyAIQQhqIQQMAQsCQCAIRQ0AAkAgAygCHCIBQQJ0IgIoAqgYIANGBEAgAkGoGGogADYCACAADQFB/BUgB0F+IAF3cSIHNgIADAILAkAgAyAIKAIQRgRAIAggADYCEAwBCyAIIAA2AhQLIABFDQELIAAgCDYCGCADKAIQIgEEQCAAIAE2AhAgASAANgIYCyADKAIUIgFFDQAgACABNgIUIAEgADYCGAsCQCAEQQ9NBEAgAyAEIAVqIgBBA3I2AgQgACADaiIAIAAoAgRBAXI2AgQMAQsgAyAFQQNyNgIEIAMgBWoiAiAEQQFyNgIEIAIgBGogBDYCACAEQf8BTQRAIARB+AFxQaAWaiEAAn9B+BUoAgAiAUEBIARBA3Z0IgVxRQRAQfgVIAEgBXI2AgAgAAwBCyAAKAIICyEBIAAgAjYCCCABIAI2AgwgAiAANgIMIAIgATYCCAwBC0EfIQAgBEH///8HTQRAIARBJiAEQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAAsgAiAANgIcIAJCADcCECAAQQJ0QagYaiEBAkACQCAHQQEgAHQiBXFFBEBB/BUgBSAHcjYCACABIAI2AgAMAQsgBEEZIABBAXZrQQAgAEEfRxt0IQAgASgCACEFA0AgBSIBKAIEQXhxIARGDQIgAEEddiEFIABBAXQhACABIAVBBHFqIgYoAhAiBQ0ACyAGIAI2AhALIAIgATYCGCACIAI2AgwgAiACNgIIDAELIAEoAggiACACNgIMIAEgAjYCCCACQQA2AhggAiABNgIMIAIgADYCCAsgA0EIaiEEC0G0GS0AAEECcUUNAEG4GRANCyAEC+0DAQR/AkAgAkEASgRAIAJB/wNNDQFB8AlBEBArQfQJEA4aAkBBlAsoAgAiAwRAQZALKAIARQ0BC0H0CRANDAILQfQKIAI2AgBB8AogATYCAEHsCiAANgIAQZALQQE2AgBB+AogA0EBaiIENgIAQfwKQQD+FwIAQYQLIAP+FwIAQYALQYAL/hACAEEBav4XAgBBiAv+EAIABEACQEGMCigCAEUEQEGMCkF/EC8MAQtBmAooAgAEQEGUCkEB/h4CABpBlApB/////wcQDwsLQfgKKAIAIQQLQfQJEA0gAkH8Cv4QAgAiA0oEQCAEQQF0IQYDQCADQQAgA0HAACACIANrIAZtIgQgBEHAAEwbIANqIgX+SAL8CiIERgR/IAEgAyAFIAIgAiAFShsgABEBAEH8Cv4QAgAFIAQLIgMgAkgNAAsLQQAhAwJAA0BBhAv+EAIAQQBMDQFBhAv+EAIAQQBMDQFBhAv+EAIAQQBMDQFBhAv+EAIAQQBMDQEgA0EEaiIDQYCAwABHDQALQfQJEA4aQYwLQQH+FwIAQYQL/hACAEEASgRAA0BBvApB9AkQJkGEC/4QAgBBAEoNAAsLQYwLQQD+FwIAQfQJEA0LQfQJEA4aQZALQQA2AgBB9AkQDQsPCyABQQAgAiAAEQEAC9IBAgN/AXxB5AAhAwJAAn8CQANAIAMEQCABBEAgASgCAA0DCyADQQFrIQMgACgCACACRg0BDAQLCyABDQBBAQwBCyABQQH+HgIAGkEACyMFIQMCQCAAKAIAIAJHDQBEAAAAAAAA8D9EAAAAAAAAWUAgAxshBiMDIQQDQAJAAkAgA0UEQCAELQApQQFHDQELA0AgBCgCJA0EIAAgAiAGEBVBt39GDQALDAELIAAgAkQAAAAAAADwfxAVGgsgACgCACACRg0ACwsNACABQQH+JQIAGgsLWgECfyAAQQdqQXhxIQIDQAJAIAJBAEHkCf4QAgAiACACaiIBIABNG0UEQCABPwBBEHRNDQEgARALDQELIwFBMDYCAEF/DwtBACAAIAH+SALkCSAARw0ACyAAC9UBAgF8AX8gAEEDcQR/QWQFEDAjBkUEQAJ/EAAhA0EAQQAgAP5IApgLGgJAEAAgAiADoCICZA0AAn8DQEEAIABBACAAQQD+SAKYCyIEIAAgBEYbRQ0BGhAwIAEgAP4QAgBGBEBBAEEAIAD+SAKYCxoQACACZA0DDAELC0F6CwwBC0EAIABBAP5IApgLGkG3fwsPC0F6Qbd/QQAgACABQn8gAkQAAAAAAECPQKJEAAAAAABAj0Ci/AYgAkQAAAAAAADwf2Eb/gECACIAQQJGGyAAQQFGGwsLCgAgABAyIAAQEAuHBAECfyACQYAETwRAIAIEQCAAIAEgAvwKAAALDwsgACACaiEDAkAgACABc0EDcUUEQAJAIABBA3FFBEAgACECDAELIAJFBEAgACECDAELIAAhAgNAIAIgAS0AADoAACABQQFqIQEgAkEBaiICQQNxRQ0BIAIgA0kNAAsLIANBfHEhAAJAIANBwABJDQAgAiAAQUBqIgRLDQADQCACIAEoAgA2AgAgAiABKAIENgIEIAIgASgCCDYCCCACIAEoAgw2AgwgAiABKAIQNgIQIAIgASgCFDYCFCACIAEoAhg2AhggAiABKAIcNgIcIAIgASgCIDYCICACIAEoAiQ2AiQgAiABKAIoNgIoIAIgASgCLDYCLCACIAEoAjA2AjAgAiABKAI0NgI0IAIgASgCODYCOCACIAEoAjw2AjwgAUFAayEBIAJBQGsiAiAETQ0ACwsgACACTQ0BA0AgAiABKAIANgIAIAFBBGohASACQQRqIgIgAEkNAAsMAQsgA0EESQRAIAAhAgwBCyACQQRJBEAgACECDAELIANBBGshBCAAIQIDQCACIAEtAAA6AAAgAiABLQABOgABIAIgAS0AAjoAAiACIAEtAAM6AAMgAUEEaiEBIAJBBGoiAiAETQ0ACwsgAiADSQRAA0AgAiABLQAAOgAAIAFBAWohASACQQFqIgIgA0cNAAsLCzABAX8gASMDIgIoAkggAEECdGoiACgCAEcEQCAAIAE2AgAgAiACLQAqQQFyOgAqCwucAwEGfyAALQAAQQ9xRQRAIABBBGpBAEEK/kgCAEEKcQ8LAn8gACgCACECAkACQAJAAkACQCMDIgEoAhgiBCAAKAIEIgNB/////wNxIgZHDQACQCACQQhxRQ0AIAAoAhRBAE4NACAAQQA2AhQgA0GAgICABHEhAwwCCyACQQNxQQFHDQBBBiAAKAIUIgFB/v///wdLDQUaIAAgAUEBajYCFAwCC0E4IQUgBkH/////A0YNAwJAIAYNAEEAIAMgAkEEcRsNACADIABBBGogAyACQYABcQR/IAEoAlBFBEAgAUF0NgJQCyAAKAIIIQYgASAAQRBqNgJUIARBgICAgHhyIAQgBhsFIAQLIANBgICAgARxcv5IAgBGDQEgAUEANgJUIAJBDHFBDEcNACAAKAIIDQQLQQoMBAsgAkEPcQ0BC0EADAILIAAgASgCTCICNgIQIAAgAUHMAGoiBTYCDCAAQRBqIQQgAiAFRwRAIAJBBGsgBDYCAAsgASAENgJMQQAhBSABQQA2AlQgA0UNACAAQQA2AhRBPiEFCyAFCwsWACAAQQD+QQIAQQJGBEAgAEEBEA8LCzEAIABBAEEB/kgCAARAIABBAUEC/kgCABoDQCAAQQBBAhATIABBAEEC/kgCAA0ACwsL8AECA38DfCMAQRBrIgQkAAJAAn8CQAJAIwUiAg0AIwMiAy0AKEEBRw0AIAMtAClFDQELRAAAAAAAAPA/RAAAAAAAAFlAIAIbIQUQAEQAAAAAAADwf6AhByMDIQIDQAJAIAIoAiRFBEAgBxAAoSIGRAAAAAAAAAAAZUUNAUHJAAwEC0ELIQAMBAsgACABIAUgBiAFIAZjGxAVIgNBt39GDQALQQAgA2sMAQtBACAAIAFEAAAAAAAA8H8QFWsLIgBBACAAQW9xQQtGGyAAIABByQBHGyIAQRtHDQBBG0EAQYgNKAIAGyEACyAEQRBqJAAgAAvJAwEDfyMAQRBrIgQkACAAEA4aAkAgAEGcC0cEQCAAIAEQNCEBDAELIwEiA0EBOgAEQZwLIAEQNCEBIANBADoABAsgABANIAEEfyAEIAIoAgg2AgggBCACKQIANwMAIwBBMGsiACQAAkACfyABKAIcIgP+EAJ8IQIDQEEAIAJFDQEaIAIgAyACIAJBAWr+SAJ8IgJHDQALQQELRQRAQQAhAwwBCyABQQRqIgIQDhogACAEKAIINgIgIAAgBCkCADcDGCABIABBGGoQNiEDIAIQDQJ/IAMEfyABQQL+QQIAIQVBASEDIAEoAhwiAiAFQQJGDQEaIAAgATYCLCAAIAE2AhAgAEESNgIoIABBEzYCJCAAIAApAiQ3AwgjAEEQayIDJAAgAigCeEEEahAOGiACKAJ4IAMgACgCEDYCCCADIAApAgg3AwAgAxA2GiACKAJ4QQRqEA0CQCACKAJ4QQL+QQIAQQJGDQAgAv4QAoABBEAgAkF//gACABoMAQsgAiMDEAwLIANBEGokAEEBBUEACyEDIAEoAhwLIgFBAf4lAnxBAUYEQCABQfwAakH/////BxAPCwsgAEEwaiQAIAMFQQALIARBEGokAAvdBAMCewd/AX0jAEEgayILJAACQCAEQQBMDQAgBUEATA0AIAQQESEMIARBCHYiDkECdBARIQ0CQCAMRQ0AIA1FDQAgBEGAAk8EQCAAIAFBAnRqIRBBACEAA0AgAEEIdCERIBAgAEEKdGohD/0MAAAAAAAAAAAAAAAAAAAAACEJQQAhAQNAIA8gAUECdGoiBP0AAjD94AEgBP0AAiD94AEgBP0AAhD94AEgBP0AAgD94AEgCf3rAf3rAf3rAf3rASEJIAFBEGoiAUGAAkcNAAsgDCARaiEBIA0gAEECdGoCfSAJIAkgCf0NCAkKCwwNDg8AAQIDAAECA/3rASIJIAkgCf0NBAUGBwABAgMAAQIDAAECA/3rAf0fACISQwAAAABcBEBDAACAPyASlf0TIQpBACEEA0AgASAEaiAPIARBAnRq/QACAP0MAAD+QgAA/kIAAP5CAAD+Qv3mASAK/eYBIgn9HwCQ/AD9ESAJ/R8BkPwA/RwBIAn9HwKQ/AD9HAIgCf0fA5D8AP0cA/0Mgf///4H///+B////gf////24Af0MfwAAAH8AAAB/AAAAfwAAAP22ASAJ/Q0ABAgMAAAAAAAAAAAAAAAA/VoAAAAgBEEEaiIEQYACRw0ACyASQwQCATyUDAELIAFBAEGAAvwLAEMAAAAACzgCACAAQQFqIgAgDkcNAAsLIAtBADYCHCALIAU2AhggCyAONgIUIAsgDTYCDCALIAw2AgggCyACIANqNgIEIAsgBiAHQQJ0ajYCECAIIAtBBGogBRASCyAMEBAgDRAQCyALQSBqJAALqAICAn8BeyMAQSBrIgkkAAJAIAVBAEwNACAEQQBMBEAgBUECdCIARQ0BIAYgB0ECdGpBACAA/AsADAELIAkgBTYCHCAJIARBBXYiCjYCGCAJIAIgA2o2AgggCSAGIAdBAnRqNgIQIAkgACABQQJ0aiICNgIMIApBAnQQESIBRQ0AIARBH0sEQEEAIQcDQCABIAdBAnRqIAIgB0EHdGoiAP0AAgAgAP0AAnD95AEgAP0AAkD95AEgAP0AAiAgAP0AAmD95AH95AEgAP0AAhAgAP0AAlD95AEgAP0AAjD95AH95AEiC/0fACAL/R8BkiAL/R8CkiAL/R8DkjgCACAHQQFqIgcgCkcNAAsLIAkgATYCFCAIIAlBCGogBRASIAEQEAsgCUEgaiQAC3cBBH9BvBEoAgAjAygCGEYEQEG8EUEANgIACwNAQbQRKAIAIQJBsBFBsBEoAgAiACAAQQFrQQAgAEH/////B3EiAUEBRxtBACABQf////8HRxsiA/5IAgAgAEcNAAsCQCADDQAgAkUgAEEATnENAEGwESABEA8LC0sBAn8CQAJAA0BBBiEBAkBBsBEoAgAiAEH/////B3FB/v///wdrDgIDAgALIABBsBEgACAAQQFq/kgCAEcNAAtBAA8LQQohAQsgAQvEAwEGfyMAQRBrIgUkAAJAIAAgACgCAEcNAAJAAkAgAEEgakECQQP+SAIAQQJrDgIBAgALIwMhASAFQQxqBEAgBSABLQAoNgIMCyABQQE6ACgQAyMAQRBrIgEkAAJAIAAgACgCAEcNAAJAIAAoAiBBA0YNACAAIwNHDQAMAQsjAyEEIAFBDGoiAwRAIAMgBC0AKDYCAAsgBEEBOgAoIAEoAgxFBEAjA0EAOgAoCwJAAkACQCAAQSBqIgYoAgAiAwRAA0AgAkEcRg0CIAJByQBGDQIgA0EDTgRAIAEoAgwiAEECTQR/IwMgADoAKEEABUEcCxoMBgtBASEEIAYgAxAcIQIgBigCACIDDQALDAILIAEoAgwiAkECTQR/IwMgAjoAKEEABUEcCxpBASEEDAILQQAhBAsgASgCDCIDQQJNBH8jAyADOgAoQQAFQRwLGiACQRxGDQEgAkHJAEYNAQsjAEEQa0EANgIMAkBBoA0oAgAiAkUNAEGgDUGoDSACEBNBqA0oAgBFDQBBoA1BARAPCyAERQ0AIAAQAQsgAUEQaiQAIAUoAgwiAEECTQR/IwMgADoAKEEABUEcCxoLCyAFQRBqJAAL1QYBBX8jAEEwayIEJAACQCAARQRAQRwhAgwBC0GsDSgCAEUEQEGsDUErNgIAC0HJCy0AAEUEQAJAQcsLLAAAIgNFDQBBjA1BAEGBgICAeP5IAgAhASADQQBIBEBBywtBADoAAAsgAUUNAANAQYwNIAFB/////wdqIAEgAUEASBsiAyADQf////8Ha/5IAgAiASADRg0BIAJBAWoiAkEKRw0AC0GMDUEB/h4CAEEBaiEBA0AgAUEASARAQYwNQQAgARATIAFB/////wdqIQELIAFBjA0gASABQYCAgIB4cv5IAgAiAUcNAAsLQZANKAIAIgEEQANAAkAgAUUNACABKAJMQQBODQAgAUEANgJMCyABKAI4IgENAAsLAkBBjA0oAgBBAE4NAEGMDUH/////B/4eAgBBgYCAgHhGDQBBjA1BARAPCwJAQZwNKAIAIgFFDQAgASgCTEEATg0AIAFBADYCTAsCQEHgCSgCACIBRQ0AIAEoAkxBAE4NACABQQA2AkwLAkBBnA0oAgAiAUUNACABKAJMQQBODQAgAUEANgJMC0HJC0EBOgAACyAEQQRqQQBBLPwLACAEQcQIKAIAIgE2AgRByAgoAgBBjwFqIgJBACABQQ9qIAQoAgwbaiIDEBEiASACEC4gASADNgIwIAEgATYCLCABIAE2AgBBrA1BrA0oAgAiAkEBajYCACABIAFBzABqNgJMIAEgAjYCGCABQegLNgJgIAFBA0ECIAQoAhAbNgIgIAEgBCgCBCIDNgI4IAEgAUGHAWpBfHEiAjYCdCACQQVqIQJByAgoAgAEQCABIAJBA2pBfHEiAjYCSEHICCgCACACaiECCyABIAQoAgwiBSACIANqQQ9qQXBxIAUbNgI0IAEQQCMDIQIQJSACKAIMIQMgASACNgIIIAEgAzYCDCADIAE2AgggASgCCCABNgIMECRBzAtBzAsoAgAiAkEBajYCACACRQRAQcsLQQE6AAALIAEgBEEEakERQQAQBSICBEBBzAtBzAsoAgBBAWsiADYCACAARQRAQcsLQQA6AAALECUgASgCDCIAIAEoAggiAzYCCCADIAA2AgwgASABNgIMIAEgATYCCBAkDAELIAAgATYCAAsgBEEwaiQAIAILNAEBf0GkDSgCACIABEBBpA0gAEEBazYCAA8LQaANQQD+FwIAQagNKAIABEBBoA1BARAPCwtRAQJ/IwMoAhgiAEGgDSgCAEcEQEGgDUEAIAD+SAIAIgEEQANAQaANQagNIAEQE0GgDUEAIAD+SAIAIgENAAsLDwtBpA1BpA0oAgBBAWo2AgALjwYBBn8jAEEgayICJAAgAkEANgIYIAJCADcDECACQgA3AwggACgCEBojBARAEAMLAkACQCABLQAAQQ9xRQ0AIwMoAhggASgCBEH/////B3FGDQAMAQsCfyAAKAIAIgcEQCAAKAIIIQMgAEEMakEB/h4CABogAEEIagwBCyAAQSBqIgMQGyACQQI2AhQgAkEANgIQIAIgACgCBCIENgIMIAAgAkEIaiIFNgIEAkAgACgCFEUEQCAAIAU2AhQMAQsgBCACQQhqNgIACyADEBpBAiEDIAJBFGoLIQUgARANIwMhBiACQQRqIgQEQCAEIAYtACg2AgALIAZBAjoAKCACKAIEQQFGBEAjA0EBOgAoCyAFIAMQHCEEAkAgBSgCACADRw0AA0AgBEEbR0EAIAQbDQEgBSADEBwhBCAFKAIAIANGDQALCyAEQQAgBEEbRxshBAJ/AkACQCAHBEAgBEELRgRAQQtBACAAKAIIIANGGyEECyAAQQxqIgNBf/4eAgBBgYCAgHhHDQIMAQsgAkEQakEAQQL+SAIARQRAIABBIGoiAxAbAkAgACgCBCACQQhqRgRAIAAgAigCDDYCBAwBCyACKAIIIgVFDQAgBSACKAIMNgIECwJAIAAoAhQgAkEIakYEQCAAIAIoAgg2AhQMAQsgAigCDCIARQ0AIAAgAigCCDYCAAsgAxAaIAIoAhgiAEUNAiAAQX/+HgIAQQFHDQIgAigCGCEDDAELIAJBFGoQGyABEA4aAkAgAigCDA0AIAEtAABBCHENACABQQhqQQH+HgIAGgsCQCACKAIIIgMEQCABKAIEIgBBAEoEQCABQQRqIAAgAEGAgICAeHL+SAIAGgsgA0EMaiIAQQD+FwIAIABB/////wcQDwwBCyABLQAAQQhxDQAgAUEIakEB/iUCABoLIAIoAgQMAgsgA0EBEA8LIAEQDiEAIAIoAgQiAUECTQR/IwMgAToAKEEABUEcCxogACAEIAAbQQtHDQFBAQsiAEECTQR/IwMgADoAKEEABUEcCxoLIAJBIGokAAtTAQN/IwBBEGsiAiQAIwMhAyACQQxqIgQEQCAEIAMtACg2AgALIANBAToAKCAAIAEQHCACKAIMIgFBAk0EfyMDIAE6AChBAAVBHAsaIAJBEGokAAttAQJ/IwBBEGsiASQAIABBATYCICAAQQRqIgIQDhogACgCLCAAKAIwRwRAA0AgAUEEaiAAEDggAhANIAEoAgwgASgCBBEAACACEA4aIAAoAiwgACgCMEcNAAsLIAIQDSAAQQA2AiAgAUEQaiQACy4AIAAoAgBFBEAgAEEBEC8PCyAAKAIMBEAgAEEIaiIAQQH+HgIAGiAAQQEQDwsLnwEBAX8CQBAhQQpHDQBB5AAhAANAAkAgAEUNAEGwESgCAEUNACAAQQFrIQBBtBEoAgBFDQELCxAhQQpHDQADQAJAQbARKAIAIgBB/////wdxQf////8HRw0AQbQRQQH+HgIAGkGwESAAQX/+SAIAGkG4ESgCABpBsBFBfxAnIQBBtBFBAf4lAgAaIABFDQAgAEEbRw0CCxAhQQpGDQALCwu0AQEDfwJAIAAoAgBBAkYEQCMAQRBrQQA2AgwMAQsjAEEQayICJAADQAJAAkACQAJAAkAgAEEAQQH+SAIADgQAAgEDBQsgAkEEaiIDIAA2AgQgAkEeNgIEIAIjAyIEKAJENgIMIAQgAzYCRCABEQIAIwMgAigCDDYCRCAAQQL+QQIAQQNHDQAgAEH/////BxAPCyACQRBqJAAMAgsgAEEBQQP+SAIAGgsgAEEAQQMQEwwBCwsLCzAAIAAoAgBBgQFOBEBBlA0oAgAiAARAA0BBlA1BmA0gABATQZQNKAIAIgANAAsLCwsnAAJAQQBBf/4eApQNQQFHDQBBmA0oAgBFDQBBlA1B/////wcQDwsL1gIBAX8CQCABRQ0AIABBADoAACAAIAFqIgJBAWtBADoAACABQQNJDQAgAEEAOgACIABBADoAASACQQNrQQA6AAAgAkECa0EAOgAAIAFBB0kNACAAQQA6AAMgAkEEa0EAOgAAIAFBCUkNACAAQQAgAGtBA3EiAmoiAEEANgIAIAAgASACa0F8cSICaiIBQQRrQQA2AgAgAkEJSQ0AIABBADYCCCAAQQA2AgQgAUEIa0EANgIAIAFBDGtBADYCACACQRlJDQAgAEEANgIYIABBADYCFCAAQQA2AhAgAEEANgIMIAFBEGtBADYCACABQRRrQQA2AgAgAUEYa0EANgIAIAFBHGtBADYCACACIABBBHFBGHIiAmsiAUEgSQ0AIAAgAmohAANAIABCADcDGCAAQgA3AxAgAEIANwMIIABCADcDACAAQSBqIQAgAUEgayIBQR9LDQALCwvyAQEFfyMAQRBrIgMkACADQQA2AgwgAEEgaiIGEBsgACgCFCICQQBHIQUCQCABRQ0AIAJFDQADQAJAIAJBCGpBAEEB/kgCAARAIAMgAygCDEEBajYCDCACIANBDGo2AhAMAQsgBCACIAQbIQQgAUEBayEBCyACKAIAIgJBAEchBSABRQ0BIAINAAsLAkAgBQRAIAIoAgQiAQRAIAFBADYCAAsgAkEANgIEDAELIABBADYCBAsgACACNgIUIAYQGiADKAIMIgIEQANAIANBDGpBACACEBMgAygCDCICDQALCyAEBEAgBEEMahAaCyADQRBqJAALYgEBfwJAIwUEQEGEDf4QAgANASMBIgAtAARFBEAgAEEBOgAEQZwLEA4aQZwLIwMQNSEAQZwLEA0CQCAARQ0AIAAoAiANACAAECgLIwFBADoABAsLDwtBhA3+EAIAEAcQBgALhwEBA38jAEEgayIBJAACQCAAKAIIRQRAIABBEGoiAhAOGiAAQQI2AgwgAhANIABBKGoQKQwBCyAAKAIYBEAgACgCECECIAAoAgwgASAANgIcIAEgADYCECABQRQ2AhggAUEZNgIUIAEgASkCFDcDCCACIAFBCGoQHQ0BCyAAEBYLIAFBIGokAAuCAQECfyAAKAIIRQRAIABBEGoQLAJAIABBKGoiACgCAEUNACAAKAIMRQ0AIABBDGoiAUGAgICAeP4zAgAaIABBCGoiAkEB/h4CABogAkH/////BxAPIAAoAgwiAEH/////B3FFDQADQCABQQAgABATIAEoAgAiAEH/////B3ENAAsLCwtlAQJ/IAAgACgCWEYEQCAAQgA3AlhBwAsoAgBBABAYDwsjAygCSEHACygCACIBQQJ0aigCACICIABGBEAgASACKAJYEBgLIAAoAlwiAiAAKAJYIgE2AlggASACNgJcIABCADcCWAueCQEOfwJAIAAgARA1IgJFBEAgACgCHCICIAAoAiBGBEACfyACQQF0QQEgAhsiD0ECdCEJIAAoAhgiDEUEQCAJEBEMAQsgCUFATwRAIwFBMDYCAEEADAELAkBBtBktAABBAnEEQEG4GRAODQELAn9BECAJQQtqQXhxIAlBC0kbIQZBACECIAxBCGsiBCgCBCIKQXhxIQgCQCAKQQNxRQRAIAZBgAJJDQEgBkEEaiAITQRAIAQhAiAIIAZrQegVKAIAQQF0TQ0CC0EADAILIAQgCGohBwJAIAYgCE0EQCAIIAZrIgNBEEkNASAEIAYgCkEBcXJBAnI2AgQgBCAGaiICIANBA3I2AgQgByAHKAIEQQFyNgIEIAIgAxA+DAELQZAWKAIAIAdGBEBBhBYoAgAgCGoiCCAGTQ0CIAQgBiAKQQFxckECcjYCBCAEIAZqIgMgCCAGayICQQFyNgIEQYQWIAI2AgBBkBYgAzYCAAwBC0GMFigCACAHRgRAQYAWKAIAIAhqIgMgBkkNAgJAIAMgBmsiAkEQTwRAIAQgBiAKQQFxckECcjYCBCAEIAZqIgggAkEBcjYCBCADIARqIgMgAjYCACADIAMoAgRBfnE2AgQMAQsgBCAKQQFxIANyQQJyNgIEIAMgBGoiAiACKAIEQQFyNgIEQQAhAkEAIQgLQYwWIAg2AgBBgBYgAjYCAAwBCyAHKAIEIgNBAnENASADQXhxIAhqIg0gBkkNASANIAZrIQ4gBygCDCEFAkAgA0H/AU0EQCAHKAIIIgIgBUYEQEH4FUH4FSgCAEF+IANBA3Z3cTYCAAwCCyACIAU2AgwgBSACNgIIDAELIAcoAhghCwJAIAUgB0cEQCAHKAIIIgIgBTYCDCAFIAI2AggMAQsCQCAHKAIUIgIEfyAHQRRqBSAHKAIQIgJFDQEgB0EQagshCANAIAghAyACIgVBFGohCCACKAIUIgINACAFQRBqIQggBSgCECICDQALIANBADYCAAwBC0EAIQULIAtFDQACQCAHKAIcIgNBAnQiAigCqBggB0YEQCACQagYaiAFNgIAIAUNAUH8FUH8FSgCAEF+IAN3cTYCAAwCCwJAIAcgCygCEEYEQCALIAU2AhAMAQsgCyAFNgIUCyAFRQ0BCyAFIAs2AhggBygCECICBEAgBSACNgIQIAIgBTYCGAsgBygCFCICRQ0AIAUgAjYCFCACIAU2AhgLIA5BD00EQCAEIApBAXEgDXJBAnI2AgQgBCANaiICIAIoAgRBAXI2AgQMAQsgBCAGIApBAXFyQQJyNgIEIAQgBmoiAyAOQQNyNgIEIAQgDWoiAiACKAIEQQFyNgIEIAMgDhA+CyAEIQILIAILIQJBtBktAABBAnEEQEG4GRANCyACQQhqIAINARpBACAJEBEiBEUNARogBCAMQXxBeCAMQQRrKAIAIgJBA3EbIAJBeHFqIgIgCSACIAlJGxAXIAwQEAsgBAsiAkUNAiAAIA82AiAgACACNgIYCyABEDoiAkUNASAAIAAoAhwiAUEBajYCHCAAKAIYIAFBAnRqIAI2AgALIAIPC0EAC0oBA38CQCAAKAIcIgJBAEwNACAAKAIYIQNBACEAA0AgASADIABBAnRqKAIAIgQoAhxHBEAgAiAAQQFqIgBHDQEMAgsLIAQPC0EAC/wBAQV/AkAgACgCLCAAKAIwQQFqIAAoAigiAm9HDQAgAkEYbBARIgMEfyACQQF0IQUCQCAAKAIwIgQgACgCLCICTgRAIAMgACgCJCACQQxsaiAEIAJrIgJBDGwQFwwBCyADIAAoAiQgAkEMbGogACgCKCACayICQQxsIgYQFyADIAZqIAAoAiQgBEEMbBAXIAIgBGohAgsgACgCJBAQIAAgAjYCMCAAQQA2AiwgACAFNgIoIAAgAzYCJEEBBUEACw0AQQAPCyAAKAIkIAAoAjBBDGxqIgMgASkCADcCACADIAEoAgg2AgggACAAKAIwQQFqIAAoAihvNgIwQQELZQEDfyMAQRBrIgEkACAAQQRqIgIQDhogACgCLCAAKAIwRwRAA0AgAUEEaiAAEDggASgCCCIDBEAgASgCDCADEQAACyAAKAIsIAAoAjBHDQALCyACEA0gAEEA/hcCACABQRBqJAALOAECfyAAIAEoAiQgASgCLCICQQxsaiIDKQIANwIAIAAgAygCCDYCCCABIAJBAWogASgCKG82AiwLFAAgAEEEahAsIAAoAiQQECAAEBAL1wIBBn8jAEFAaiIBJABBjAgQGUUEQEHACCgCACICQYgIRwRAA0AgAigCOCAC/hACAEUEQCACKAI0IgQgAigCOCIFNgI4IAUgBDYCNCACEDkLIgJBiAhHDQALC0GMCBANCwJAQTwQESICRQ0AQYAMEBEiA0UEQCACEBAMAQsgAUIANwMoIAFCADcDMCABQQA2AjwgAUIANwMgIAEgADYCHCABQQA2AhggASADNgIUIAFBgAE2AhAgAUEANgIMIAFBADYCCCABQQA2AgQgAUEANgIAIAIgASgCPDYCACACIAEpAzA3AhQgAiABKQMoNwIMIAIgASkDIDcCBCACIAEoAhw2AhwgAiABKAIYNgIgIAIgASgCFDYCJCACIAEoAhA2AiggAiABKAIMNgIsIAIgASgCCDYCMCACIAEoAgQ2AjQgAiABKAIANgI4IAIhBgsgAUFAayQAIAYLghMEA3sGfwF9AX4gAC0A0QEiCEEHdiEHIAhBCHQiCiAALQDQAXJB/wdxIQkCfQJAIAhBAnZBH3EiCEEfRwRAIAgNASAHQR90viAJRQ0CGiAJs0MAAIAzlCINjCANIArBQQBIGwwCCyAHQR90QYCAgAJBACAJG3JBgICA/AdyvgwBCyAIQRd0IAdBH3RyIAlBDXRyQYCAgMADar4LIAD9AAAgIQUgAyAA/QAAgAEiBP0MMDAwMDAwMDAwMDAwMDAwMP1OIAD9AAAAIgZBBP1t/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAEAgAyAEQQL9bf0MMDAwMDAwMDAwMDAwMDAwMP1OIAVBBP1t/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAGAgAyAEQQL9a/0MMDAwMDAwMDAwMDAwMDAwMP1OIAX9DA8PDw8PDw8PDw8PDw8PDw/9Tv1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwAgIAMgBEEE/Wv9DDAwMDAwMDAwMDAwMDAwMDD9TiAG/QwPDw8PDw8PDw8PDw8PDw8P/U79UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAACAA/QAAMCEFIAMgAP0AAJABIgT9DDAwMDAwMDAwMDAwMDAwMDD9TiAA/QAAECIGQQT9bf1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwBQIAMgBEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9TiAFQQT9bf1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwBwIAMgBEEC/Wv9DDAwMDAwMDAwMDAwMDAwMDD9TiAF/QwPDw8PDw8PDw8PDw8PDw8P/U79UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAMCADIARBBP1r/QwwMDAwMDAwMDAwMDAwMDAw/U4gBv0MDw8PDw8PDw8PDw8PDw8PD/1O/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LABAgAP0AAGAhBSADIAD9AACgASIE/QwwMDAwMDAwMDAwMDAwMDAw/U4gAP0AAEAiBkEE/W39UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAwAEgAyAEQQL9bf0MMDAwMDAwMDAwMDAwMDAwMP1OIAVBBP1t/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAOABIAMgBEEC/Wv9DDAwMDAwMDAwMDAwMDAwMDD9TiAF/QwPDw8PDw8PDw8PDw8PDw8P/U79UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsAoAEgAyAEQQT9a/0MMDAwMDAwMDAwMDAwMDAwMP1OIAb9DA8PDw8PDw8PDw8PDw8PDw/9Tv1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwCAASAA/QAAcCEFIAMgAP0AALABIgT9DDAwMDAwMDAwMDAwMDAwMDD9TiAA/QAAUCIGQQT9bf1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwDQASADIARBAv1t/QwwMDAwMDAwMDAwMDAwMDAw/U4gBUEE/W39UP0M4ODg4ODg4ODg4ODg4ODg4P1u/QsA8AEgAyAEQQL9a/0MMDAwMDAwMDAwMDAwMDAwMP1OIAX9DA8PDw8PDw8PDw8PDw8PDw/9Tv1Q/Qzg4ODg4ODg4ODg4ODg4ODg/W79CwCwASADIARBBP1r/QwwMDAwMDAwMDAwMDAwMDAw/U4gBv0MDw8PDw8PDw8PDw8PDw8PD/1O/VD9DODg4ODg4ODg4ODg4ODg4OD9bv0LAJABIABBwAFqIQhBACEAQQEhCQNAIABBB3QhCiAIIABBA3RqIQtBACEAA0AgCyAAQQF0aiIMMAAAIAMgAEEFdCAKaiIHav0AAAAiBP2HAf2nASABIAdq/QAAACIF/YcB/acB/dwBIAQgBP0NCAkAAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQgJAAAAAAAAAAAAAAAAAAD9hwH9pwH93AH9zgEgBCAE/Q0EBQAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NBAUAAAAAAAAAAAAAAAAAAP2HAf2nAf3cASAEIAT9DQwNAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0MDQAAAAAAAAAAAAAAAAAA/YcB/acB/dwB/c4B/c4BIAQgBP0NAgMAAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQIDAAAAAAAAAAAAAAAAAAD9hwH9pwH93AEgBCAE/Q0KCwAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NCgsAAAAAAAAAAAAAAAAAAP2HAf2nAf3cAf3OASAEIAT9DQYHAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0GBwAAAAAAAAAAAAAAAAAA/YcB/acB/dwBIAQgBP0NDg8AAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQ4PAAAAAAAAAAAAAAAAAAD9hwH9pwH93AH9zgH9zgH9zgEiBCAEIAT9DQgJCgsMDQ4PAAECAwQFBgf9zgH9HQB+IA58IAwwAAEgAyAHQRByIgdq/QAAACIE/YcB/acBIAEgB2r9AAAAIgX9hwH9pwH93AEgBCAE/Q0ICQAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NCAkAAAAAAAAAAAAAAAAAAP2HAf2nAf3cAf3OASAEIAT9DQQFAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0EBQAAAAAAAAAAAAAAAAAA/YcB/acB/dwBIAQgBP0NDA0AAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQwNAAAAAAAAAAAAAAAAAAD9hwH9pwH93AH9zgH9zgEgBCAE/Q0CAwAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NAgMAAAAAAAAAAAAAAAAAAP2HAf2nAf3cASAEIAT9DQoLAAAAAAAAAAAAAAAAAAD9hwH9pwEgBSAE/Q0KCwAAAAAAAAAAAAAAAAAA/YcB/acB/dwB/c4BIAQgBP0NBgcAAAAAAAAAAAAAAAAAAP2HAf2nASAFIAT9DQYHAAAAAAAAAAAAAAAAAAD9hwH9pwH93AEgBCAE/Q0ODwAAAAAAAAAAAAAAAAAA/YcB/acBIAUgBP0NDg8AAAAAAAAAAAAAAAAAAP2HAf2nAf3cAf3OAf3OAf3OASIEIAQgBP0NCAkKCwwNDg8AAQIDBAUGB/3OAf0dAH58IQ4gAEEBaiIAQQRHDQALQQEhACAJQQAhCQ0ACyAClCAOtJQL5DUDGnsGfwJ9IAAtAAEiH0EHdiEdIAAtAANBCHQiICAALQACciEeIB9BCHQiISAALQAAckH/B3EhHAJ9AkAgH0ECdkEfcSIfQR9HBEAgHw0BIB1BH3S+IBxFDQIaIByzQwAAgDOUIiKMICIgIcFBAEgbDAILIB1BH3RBgICAAkEAIBwbckGAgID8B3K+DAELIB9BF3QgHUEfdHIgHEENdHJBgICAwANqvgshIyAeQf8HcSEcIB5BgIACcUEPdiEdIAH9AALwASIDIAD9XAAs/YkB/akBIgRBA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XABM/YkB/akBIgJBBP2tAf1Q/foB/eYBIAH9AALgASIGIAD9XAAo/YkB/akBIg5BA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XABI/YkB/akBIgdBBP2tAf1Q/foB/eYBIAH9AALQASIIIAD9XAAk/YkB/akBIg9BA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XABE/YkB/akBIglBBP2tAf1Q/foB/eYBIAH9AALAASIKIAD9XAAg/YkB/akBIhBBA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XABA/YkB/akBIgtBBP2tAf1Q/foB/eYBIAH9AAKwASIMIAD9XAAc/YkB/akBIhFBA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XAA8/YkB/akBIgVBBP2tAf1Q/foB/eYBIAH9AAKgASIVIAD9XAAY/YkB/akBIhJBA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XAA4/YkB/akBIhZBBP2tAf1Q/foB/eYBIAH9AAKQASIXIAD9XAAU/YkB/akBIhNBA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XAA0/YkB/akBIhhBBP2tAf1Q/foB/eYBIAH9AAKAASIZIAD9XAAQ/YkB/akBIhpBA/2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XAAw/YkB/akBIhtBBP2tAf1Q/foB/eYB/eQB/eQB/eQB/eQB/eQB/eQB/eQBIhQgFP0MEAAAABAAAAAQAAAAEAAAAP0NBAUGBwABAgMMDQ4PAAECA/3kASIUIBT9DBAAAAAQAAAAEAAAABAAAAD9DQgJCgsAAQIDAAECAwABAgP95AEgAyAGIAggCiAMIBUgFyAZ/eQB/eQB/eQB/eQB/eQB/eQB/eQBIgMgA/0MEAAAABAAAAAQAAAAEAAAAP0NBAUGBwABAgMMDQ4PAAECA/3kASIDIAP9DBAAAAAQAAAAEAAAABAAAAD9DQgJCgsAAQIDAAECAwABAgP95AH9HwACfQJAIB5BCnZBH3EiHkEfRwRAIB4NASAdQR90viAcRQ0CGiAcs0MAAIAzlCIijCAiICDBQQBIGwwCCyAdQR90QYCAgAJBACAcG3JBgICA/AdyvgwBCyAeQRd0IB1BH3RyIBxBDXRyQYCAgMADar4LIiKU/SABIAD9XQAEIgP9FgFBP3Gy/RMgA/0WBUE/cbL9IAH95gEgAf0AAnAiBiAEQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAC/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACYCICIA5BBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAf9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAJQIgcgD0EE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gCf0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAkAiCCAQQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAL/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACMCIJIBFBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAX9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAIgIgogEkEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gFv0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAhAiCyATQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAY/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACACIMIBpBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBv9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYB/eQB/eQB/eQB/eQB/eQB/eQB/eQBIgUgBf0MEAAAABAAAAAQAAAAEAAAAP0NBAUGBwABAgMMDQ4PAAECA/3kASIFIAX9DBAAAAAQAAAAEAAAABAAAAD9DQgJCgsAAQIDAAECAwABAgP95AEgBiACIAcgCCAJIAogCyAM/eQB/eQB/eQB/eQB/eQB/eQB/eQBIgIgAv0MEAAAABAAAAAQAAAAEAAAAP0NBAUGBwABAgMMDQ4PAAECA/3kASICIAL9DBAAAAAQAAAAEAAAABAAAAD9DQgJCgsAAQIDAAECAwABAgP95AH9HwAgIpT9IAEgA/0WAEE/cbL9EyAD/RYEQT9xsv0gAf3mAf3kASAB/QAC8AMiAiAEQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAbP2JAf2pASIGQQT9rQH9UP36Af3mASAB/QAC4AMiByAOQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAaP2JAf2pASIIQQT9rQH9UP36Af3mASAB/QAC0AMiCSAPQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAZP2JAf2pASIKQQT9rQH9UP36Af3mASAB/QACwAMiCyAQQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAYP2JAf2pASIMQQT9rQH9UP36Af3mASAB/QACsAMiBSARQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAXP2JAf2pASIVQQT9rQH9UP36Af3mASAB/QACoAMiFiASQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAWP2JAf2pASIXQQT9rQH9UP36Af3mASAB/QACkAMiGCATQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAVP2JAf2pASIZQQT9rQH9UP36Af3mASAB/QACgAMiGyAaQQH9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAUP2JAf2pASIUQQT9rQH9UP36Af3mAf3kAf3kAf3kAf3kAf3kAf3kAf3kASINIA39DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiDSAN/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQBIAIgByAJIAsgBSAWIBggG/3kAf3kAf3kAf3kAf3kAf3kAf3kASICIAL9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AICKU/SABIAP9FgNBP3Gy/RMgA/0WB0E/cbL9IAH95gEgAf0AAvACIgIgBEEC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gBv0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAuACIgYgDkEC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gCP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAtACIgcgD0EC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gCv0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAsACIgggEEEC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gDP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AArACIgkgEUEC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gFf0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAqACIgogEkEC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gF/0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AApACIgsgE0EC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gGf0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAoACIgwgGkEC/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gFP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gH95AH95AH95AH95AH95AH95AH95AEiBSAF/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIgUgBf0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kASACIAYgByAIIAkgCiALIAz95AH95AH95AH95AH95AH95AH95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0EBQYHAAECAwwNDg8AAQID/eQBIgIgAv0MEAAAABAAAAAQAAAAEAAAAP0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAilP0gASAD/RYCQT9xsv0TIAP9FgZBP3Gy/SAB/eYB/eQB/eQBIAH9AALwBSICIARBAf2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACMAf2JAf2pASIGQQT9rQH9UP36Af3mASAB/QAC4AUiByAOQQH9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAiAH9iQH9qQEiCEEE/a0B/VD9+gH95gEgAf0AAtAFIgkgD0EB/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAIQB/YkB/akBIgpBBP2tAf1Q/foB/eYBIAH9AALABSILIBBBAf2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACAAf2JAf2pASIMQQT9rQH9UP36Af3mASAB/QACsAUiBSARQQH9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAfP2JAf2pASIVQQT9rQH9UP36Af3mASAB/QACoAUiFiASQQH9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAeP2JAf2pASIXQQT9rQH9UP36Af3mASAB/QACkAUiGCATQQH9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAdP2JAf2pASIZQQT9rQH9UP36Af3mASAB/QACgAUiGyAaQQH9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAcP2JAf2pASIUQQT9rQH9UP36Af3mAf3kAf3kAf3kAf3kAf3kAf3kAf3kASINIA39DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiDSAN/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQBIAIgByAJIAsgBSAWIBggG/3kAf3kAf3kAf3kAf3kAf3kAf3kASICIAL9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AICKU/SABIAAtAA0iHEEPcf0PIBxBBHb9FwEgA/0MEAAAABAAAAAQAAAAEAAAAP0NAQUAAAAAAAAAAAAAAAAAAEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9Tv1QIgL9FgCy/RMgAv0WAbL9IAH95gEgAf0AAvAEIgIgBP0MEAAAABAAAAAQAAAAEAAAAP1OIAb9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AALgBCIGIA79DBAAAAAQAAAAEAAAABAAAAD9TiAI/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QAC0AQiByAP/QwQAAAAEAAAABAAAAAQAAAA/U4gCv0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAsAEIgggEP0MEAAAABAAAAAQAAAAEAAAAP1OIAz9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKwBCIJIBH9DBAAAAAQAAAAEAAAABAAAAD9TiAV/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mASAB/QACoAQiCiAS/QwQAAAAEAAAABAAAAAQAAAA/U4gF/0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AApAEIgsgE/0MEAAAABAAAAAQAAAAEAAAAP1OIBn9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/foB/eYBIAH9AAKABCIMIBr9DBAAAAAQAAAAEAAAABAAAAD9TiAU/QwPAAAADwAAAA8AAAAPAAAA/U79UP36Af3mAf3kAf3kAf3kAf3kAf3kAf3kAf3kASIFIAX9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiBSAF/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQBIAIgBiAHIAggCSAKIAsgDP3kAf3kAf3kAf3kAf3kAf3kAf3kASICIAL9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AICKU/SABIAAtAAwiHEEPcf0PIBxBBHb9FwEgA/0MEAAAABAAAAAQAAAAEAAAAP0NAAQAAAAAAAAAAAAAAAAAAEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9Tv1QIgL9FgCy/RMgAv0WAbL9IAH95gH95AH95AEgAf0AAvAHIgIgBEED/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAKwB/YkB/akBIgZBBP2tAf1Q/foB/eYBIAH9AALgByIHIA5BA/2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACoAf2JAf2pASIIQQT9rQH9UP36Af3mASAB/QAC0AciCSAPQQP9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwApAH9iQH9qQEiCkEE/a0B/VD9+gH95gEgAf0AAsAHIgsgEEED/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAKAB/YkB/akBIgxBBP2tAf1Q/foB/eYBIAH9AAKwByIFIBFBA/2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACcAf2JAf2pASIVQQT9rQH9UP36Af3mASAB/QACoAciFiASQQP9rQH9DBAAAAAQAAAAEAAAABAAAAD9TiAA/VwAmAH9iQH9qQEiF0EE/a0B/VD9+gH95gEgAf0AApAHIhggE0ED/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gAP1cAJQB/YkB/akBIhlBBP2tAf1Q/foB/eYBIAH9AAKAByIbIBpBA/2tAf0MEAAAABAAAAAQAAAAEAAAAP1OIAD9XACQAf2JAf2pASIUQQT9rQH9UP36Af3mAf3kAf3kAf3kAf3kAf3kAf3kAf3kASINIA39DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiDSAN/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQBIAIgByAJIAsgBSAWIBggG/3kAf3kAf3kAf3kAf3kAf3kAf3kASICIAL9DBAAAAAQAAAAEAAAABAAAAD9DQQFBgcAAQIDDA0ODwABAgP95AEiAiAC/QwQAAAAEAAAABAAAAAQAAAA/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AICKU/SABIAAtAA8iHEEPcf0PIBxBBHb9FwEgA/0MEAAAABAAAAAQAAAAEAAAAP0NAwcAAAAAAAAAAAAAAAAAAEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9Tv1QIgL9FgCy/RMgAv0WAbL9IAH95gEgAf0AAvAGIgIgBEEC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gBv0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAuAGIgYgDkEC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gCP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAtAGIg4gD0EC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gCv0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAsAGIg8gEEEC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gDP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AArAGIhAgEUEC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gFf0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAqAGIhEgEkEC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gF/0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AApAGIhIgE0EC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gGf0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gEgAf0AAoAGIhMgGkEC/a0B/QwQAAAAEAAAABAAAAAQAAAA/U4gFP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9+gH95gH95AH95AH95AH95AH95AH95AH95AEiBCAEIAT9DQQFBgcAAQIDDA0ODwABAgP95AEiBCAEIAT9DQgJCgsAAQIDAAECAwABAgP95AEgAiAGIA4gDyAQIBEgEiAT/eQB/eQB/eQB/eQB/eQB/eQB/eQBIgQgBCAE/Q0EBQYHAAECAwwNDg8AAQID/eQBIgQgBCAE/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AICKU/SABIAAtAA4iAEEPcf0PIABBBHb9FwEgAyAE/Q0CBgAAAAAAAAAAAAAAAAAAQQL9bf0MMDAwMDAwMDAwMDAwMDAwMP1O/VAiA/0WALL9EyAD/RYBsv0gAf3mAf3kAf3kASID/R8AICOUIAP9HwGTC4soAxV7Bn8BfSAALQABIhtBB3YhGSAALQADQQh0IhwgAC0AAnIhGiAbQQh0Ih0gAC0AAHJB/wdxIRgCfQJAIBtBAnZBH3EiG0EfRwRAIBsNASAZQR90viAYRQ0CGiAYs0MAAIAzlCIejCAeIB3BQQBIGwwCCyAZQR90QYCAgAJBACAYG3JBgICA/AdyvgwBCyAbQRd0IBlBH3RyIBhBDXRyQYCAgMADar4LIBpB/wdxIRggGkGAgAJxQQ92IRn9EwJ9AkAgGkEKdkEfcSIaQR9HBEAgGg0BIBlBH3S+IBhFDQIaIBizQwAAgDOUIh6MIB4gHMFBAEgbDAILIBlBH3RBgICAAkEAIBgbckGAgID8B3K+DAELIBpBF3QgGUEfdHIgGEENdHJBgICAwANqvgv9IAEgAP1cACz9iQH9qQEiBEEE/a0BIAH9XAA8/YcB/acBIgP9tQEgAP1cACj9iQH9qQEiBUEE/a0BIAH9XAA4/YcB/acBIhD9tQEgAP1cACT9iQH9qQEiDEEE/a0BIAH9XAA0/YcB/acBIgb9tQEgAP1cACD9iQH9qQEiCEEE/a0BIAH9XAAw/YcB/acBIgn9tQEgAP1cABz9iQH9qQEiCkEE/a0BIAH9XAAs/YcB/acBIgf9tQEgAP1cABj9iQH9qQEiC0EE/a0BIAH9XAAo/YcB/acBIg39tQEgAP1cABT9iQH9qQEiDkEE/a0BIAH9XAAk/YcB/acBIhH9tQEgAP1cABD9iQH9qQEiEkEE/a0BIAH9XAAg/YcB/acBIhP9tQH9rgH9rgH9rgH9rgH9rgH9rgH9rgEiDyAPIAP9DQgJCgsMDQ4PAAECAwABAgP9rgEiDyAPIAP9DQQFBgcAAQIDAAECAwABAgP9rgEgEyAR/a4BIA39rgEgB/2uASAJ/a4BIAb9rgEgEP2uASAD/a4BIgMgAyAD/Q0ICQoLDA0ODwABAgMAAQID/a4BIgMgAyAD/Q0EBQYHAAECAwABAgMAAQID/a4B/Q0AAQIDEBESEwABAgMAAQID/ccBIAD9XQAEIhAgA/0NAQUAAAAAAAAAAAAAAAAAACID/Qw/Pz8/Pz8/Pz8/Pz8/Pz8//U79iQH9qQH9yQH91QEgBP0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAc/YcB/acBIgT9tQEgBf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAY/YcB/acBIgX9tQEgDP0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAU/YcB/acBIgz9tQEgCP0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAQ/YcB/acBIgb9tQEgCv0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAM/YcB/acBIgj9tQEgC/0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAI/YcB/acBIgn9tQEgDv0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAE/YcB/acBIgr9tQEgEv0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XAAA/YcB/acBIgf9tQH9rgH9rgH9rgH9rgH9rgH9rgH9rgEiCyAL/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIgsgC/0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uASAHIAr9rgEgCf2uASAI/a4BIAb9rgEgDP2uASAF/a4BIAT9rgEiBCAE/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIgQgBP0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uAf0NAAECAxAREhMAAQIDAAECA/3HASAQ/QwPAAAADwAAAA8AAAAPAAAA/Q0ABAAAAAAAAAAAAAAAAAAAIgT9DD8/Pz8/Pz8/Pz8/Pz8/Pz/9Tv2JAf2pAf3JAf3VAf3OASAA/VwATP2JAf2pASIF/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAFz9hwH9pwEiDP21ASAA/VwASP2JAf2pASIG/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAFj9hwH9pwEiCP21ASAA/VwARP2JAf2pASIJ/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAFT9hwH9pwEiCv21ASAA/VwAQP2JAf2pASIH/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAFD9hwH9pwEiC/21ASAA/VwAPP2JAf2pASIN/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAEz9hwH9pwEiDv21ASAA/VwAOP2JAf2pASIR/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAEj9hwH9pwEiEv21ASAA/VwANP2JAf2pASIT/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAET9hwH9pwEiD/21ASAA/VwAMP2JAf2pASIV/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAED9hwH9pwEiFP21Af2uAf2uAf2uAf2uAf2uAf2uAf2uASIWIBb9DA8AAAAPAAAADwAAAA8AAAD9DQgJCgsMDQ4PAAECAwABAgP9rgEiFiAW/QwPAAAADwAAAA8AAAAPAAAA/Q0EBQYHAAECAwABAgMAAQID/a4BIBQgD/2uASAS/a4BIA79rgEgC/2uASAK/a4BIAj9rgEgDP2uASIMIAz9DA8AAAAPAAAADwAAAA8AAAD9DQgJCgsMDQ4PAAECAwABAgP9rgEiDCAM/QwPAAAADwAAAA8AAAAPAAAA/Q0EBQYHAAECAwABAgMAAQID/a4B/Q0AAQIDEBESEwABAgMAAQID/ccBIBD9DA8AAAAPAAAADwAAAA8AAAD9DQIGAAAAAAAAAAAAAAAAAAAiDP0MPz8/Pz8/Pz8/Pz8/Pz8/P/1O/YkB/akB/ckB/dUB/c4BIAVBBP2tASAB/VwAfP2HAf2nASIF/bUBIAZBBP2tASAB/VwAeP2HAf2nASIG/bUBIAlBBP2tASAB/VwAdP2HAf2nASII/bUBIAdBBP2tASAB/VwAcP2HAf2nASIJ/bUBIA1BBP2tASAB/VwAbP2HAf2nASIK/bUBIBFBBP2tASAB/VwAaP2HAf2nASIH/bUBIBNBBP2tASAB/VwAZP2HAf2nASIL/bUBIBVBBP2tASAB/VwAYP2HAf2nASIN/bUB/a4B/a4B/a4B/a4B/a4B/a4B/a4BIg4gDv0MDwAAAA8AAAAPAAAADwAAAP0NCAkKCwwNDg8AAQIDAAECA/2uASIOIA79DA8AAAAPAAAADwAAAA8AAAD9DQQFBgcAAQIDAAECAwABAgP9rgEgDSAL/a4BIAf9rgEgCv2uASAJ/a4BIAj9rgEgBv2uASAF/a4BIgUgBf0MDwAAAA8AAAAPAAAADwAAAP0NCAkKCwwNDg8AAQIDAAECA/2uASIFIAX9DA8AAAAPAAAADwAAAA8AAAD9DQQFBgcAAQIDAAECAwABAgP9rgH9DQABAgMQERITAAECAwABAgP9xwEgEP0MDwAAAA8AAAAPAAAADwAAAP0NAwcAAAAAAAAAAAAAAAAAACIQ/Qw/Pz8/Pz8/Pz8/Pz8/Pz8//U79iQH9qQH9yQH91QH9zgEgAP1cAGz9iQH9qQEiBf0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XACcAf2HAf2nASIG/bUBIAD9XABo/YkB/akBIgj9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAmAH9hwH9pwEiCf21ASAA/VwAZP2JAf2pASIK/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAJQB/YcB/acBIgf9tQEgAP1cAGD9iQH9qQEiC/0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XACQAf2HAf2nASIN/bUBIAD9XABc/YkB/akBIg79DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAjAH9hwH9pwEiEf21ASAA/VwAWP2JAf2pASIS/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAIgB/YcB/acBIhP9tQEgAP1cAFT9iQH9qQEiD/0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XACEAf2HAf2nASIV/bUBIAD9XABQ/YkB/akBIhT9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAgAH9hwH9pwEiFv21Af2uAf2uAf2uAf2uAf2uAf2uAf2uASIXIBf9DA8AAAAPAAAADwAAAA8AAAD9DQgJCgsMDQ4PAAECAwABAgP9rgEiFyAX/QwPAAAADwAAAA8AAAAPAAAA/Q0EBQYHAAECAwABAgMAAQID/a4BIBYgFf2uASAT/a4BIBH9rgEgDf2uASAH/a4BIAn9rgEgBv2uASIGIAb9DA8AAAAPAAAADwAAAA8AAAD9DQgJCgsMDQ4PAAECAwABAgP9rgEiBiAG/QwPAAAADwAAAA8AAAAPAAAA/Q0EBQYHAAECAwABAgMAAQID/a4B/Q0AAQIDEBESEwABAgMAAQID/ccBIAAtAAwiGEEPcf0PIBhBBHb9FwEgBEEC/W39DDAwMDAwMDAwMDAwMDAwMDD9Tv1Q/YkB/akB/ckB/dUB/c4BIAVBBP2tASAB/VwAvAH9hwH9pwEiBP21ASAIQQT9rQEgAf1cALgB/YcB/acBIgX9tQEgCkEE/a0BIAH9XAC0Af2HAf2nASIG/bUBIAtBBP2tASAB/VwAsAH9hwH9pwEiCP21ASAOQQT9rQEgAf1cAKwB/YcB/acBIgn9tQEgEkEE/a0BIAH9XACoAf2HAf2nASIK/bUBIA9BBP2tASAB/VwApAH9hwH9pwEiB/21ASAUQQT9rQEgAf1cAKAB/YcB/acBIgv9tQH9rgH9rgH9rgH9rgH9rgH9rgH9rgEiDSAN/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIg0gDf0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uASALIAf9rgEgCv2uASAJ/a4BIAj9rgEgBv2uASAF/a4BIAT9rgEiBCAE/QwPAAAADwAAAA8AAAAPAAAA/Q0ICQoLDA0ODwABAgMAAQID/a4BIgQgBP0MDwAAAA8AAAAPAAAADwAAAP0NBAUGBwABAgMAAQIDAAECA/2uAf0NAAECAxAREhMAAQIDAAECA/3HASAALQANIhhBD3H9DyAYQQR2/RcBIANBAv1t/QwwMDAwMDAwMDAwMDAwMDAw/U79UP2JAf2pAf3JAf3VAf3OASAA/VwAjAH9iQH9qQEiBP0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XADcAf2HAf2nASIF/bUBIAD9XACIAf2JAf2pASIG/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cANgB/YcB/acBIgj9tQEgAP1cAIQB/YkB/akBIgn9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwA1AH9hwH9pwEiCv21ASAA/VwAgAH9iQH9qQEiB/0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XADQAf2HAf2nASIL/bUBIAD9XAB8/YkB/akBIg39DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAzAH9hwH9pwEiDv21ASAA/VwAeP2JAf2pASIR/QwPAAAADwAAAA8AAAAPAAAA/U4gAf1cAMgB/YcB/acBIhL9tQEgAP1cAHT9iQH9qQEiE/0MDwAAAA8AAAAPAAAADwAAAP1OIAH9XADEAf2HAf2nASIP/bUBIAD9XABw/YkB/akBIhX9DA8AAAAPAAAADwAAAA8AAAD9TiAB/VwAwAH9hwH9pwEiA/21Af2uAf2uAf2uAf2uAf2uAf2uAf2uASIUIBQgA/0NCAkKCwwNDg8AAQIDAAECA/2uASIUIBQgA/0NBAUGBwABAgMAAQIDAAECA/2uASADIA/9rgEgEv2uASAO/a4BIAv9rgEgCv2uASAI/a4BIAX9rgEiAyADIAP9DQgJCgsMDQ4PAAECAwABAgP9rgEiAyADIAP9DQQFBgcAAQIDAAECAwABAgP9rgH9DQABAgMQERITAAECAwABAgP9xwEgAC0ADiIYQQ9x/Q8gGEEEdv0XASAMQQL9bf0MMDAwMDAwMDAwMDAwMDAwMP1O/VD9iQH9qQH9yQH91QH9zgEgBEEE/a0BIAH9XAD8Af2HAf2nASID/bUBIAZBBP2tASAB/VwA+AH9hwH9pwEiBP21ASAJQQT9rQEgAf1cAPQB/YcB/acBIgX9tQEgB0EE/a0BIAH9XADwAf2HAf2nASIM/bUBIA1BBP2tASAB/VwA7AH9hwH9pwEiBv21ASARQQT9rQEgAf1cAOgB/YcB/acBIgj9tQEgE0EE/a0BIAH9XADkAf2HAf2nASIJ/bUBIBVBBP2tASAB/VwA4AH9hwH9pwEiCv21Af2uAf2uAf2uAf2uAf2uAf2uAf2uASIHIAcgA/0NCAkKCwwNDg8AAQIDAAECA/2uASIHIAcgA/0NBAUGBwABAgMAAQIDAAECA/2uASAKIAn9rgEgCP2uASAG/a4BIAz9rgEgBf2uASAE/a4BIAP9rgEiAyADIAP9DQgJCgsMDQ4PAAECAwABAgP9rgEiAyADIAP9DQQFBgcAAQIDAAECAwABAgP9rgH9DQABAgMQERITAAECAwABAgP9xwEgAC0ADyIAQQ9x/Q8gAEEEdv0XASAQQQL9bf0MMDAwMDAwMDAwMDAwMDAwMP1O/VD9iQH9qQH9yQH91QH9zgEiA/0dALT9EyAD/R0BtP0gAf3mASID/R8AIAP9HwGTIAKUC40LAQd/IAAgAWohBQJAAkAgACgCBCICQQFxDQAgAkECcUUNASAAKAIAIgIgAWohAQJAAkACQCAAIAJrIgBBjBYoAgBHBEAgACgCDCEDIAJB/wFNBEAgAyAAKAIIIgRHDQJB+BVB+BUoAgBBfiACQQN2d3E2AgAMBQsgACgCGCEGIAAgA0cEQCAAKAIIIgIgAzYCDCADIAI2AggMBAsgACgCFCIEBH8gAEEUagUgACgCECIERQ0DIABBEGoLIQIDQCACIQcgBCIDQRRqIQIgAygCFCIEDQAgA0EQaiECIAMoAhAiBA0ACyAHQQA2AgAMAwsgBSgCBCICQQNxQQNHDQNBgBYgATYCACAFIAJBfnE2AgQgACABQQFyNgIEIAUgATYCAA8LIAQgAzYCDCADIAQ2AggMAgtBACEDCyAGRQ0AAkAgACgCHCICQQJ0IgQoAqgYIABGBEAgBEGoGGogAzYCACADDQFB/BVB/BUoAgBBfiACd3E2AgAMAgsCQCAAIAYoAhBGBEAgBiADNgIQDAELIAYgAzYCFAsgA0UNAQsgAyAGNgIYIAAoAhAiAgRAIAMgAjYCECACIAM2AhgLIAAoAhQiAkUNACADIAI2AhQgAiADNgIYCwJAAkACQAJAIAUoAgQiAkECcUUEQEGQFigCACAFRgRAQZAWIAA2AgBBhBZBhBYoAgAgAWoiATYCACAAIAFBAXI2AgQgAEGMFigCAEcNBkGAFkEANgIAQYwWQQA2AgAPC0GMFigCACIIIAVGBEBBjBYgADYCAEGAFkGAFigCACABaiIBNgIAIAAgAUEBcjYCBCAAIAFqIAE2AgAPCyACQXhxIAFqIQEgBSgCDCEDIAJB/wFNBEAgBSgCCCIEIANGBEBB+BVB+BUoAgBBfiACQQN2d3E2AgAMBQsgBCADNgIMIAMgBDYCCAwECyAFKAIYIQYgAyAFRwRAIAUoAggiAiADNgIMIAMgAjYCCAwDCyAFKAIUIgQEfyAFQRRqBSAFKAIQIgRFDQIgBUEQagshAgNAIAIhByAEIgNBFGohAiADKAIUIgQNACADQRBqIQIgAygCECIEDQALIAdBADYCAAwCCyAFIAJBfnE2AgQgACABQQFyNgIEIAAgAWogATYCAAwDC0EAIQMLIAZFDQACQCAFKAIcIgJBAnQiBCgCqBggBUYEQCAEQagYaiADNgIAIAMNAUH8FUH8FSgCAEF+IAJ3cTYCAAwCCwJAIAUgBigCEEYEQCAGIAM2AhAMAQsgBiADNgIUCyADRQ0BCyADIAY2AhggBSgCECICBEAgAyACNgIQIAIgAzYCGAsgBSgCFCICRQ0AIAMgAjYCFCACIAM2AhgLIAAgAUEBcjYCBCAAIAFqIAE2AgAgACAIRw0AQYAWIAE2AgAPCyABQf8BTQRAIAFB+AFxQaAWaiECAn9B+BUoAgAiA0EBIAFBA3Z0IgFxRQRAQfgVIAEgA3I2AgAgAgwBCyACKAIICyEBIAIgADYCCCABIAA2AgwgACACNgIMIAAgATYCCA8LQR8hAyABQf///wdNBEAgAUEmIAFBCHZnIgJrdkEBcSACQQF0a0E+aiEDCyAAIAM2AhwgAEIANwIQIANBAnRBqBhqIQICQAJAQfwVKAIAIgRBASADdCIHcUUEQEH8FSAEIAdyNgIAIAIgADYCACAAIAI2AhgMAQsgAUEZIANBAXZrQQAgA0EfRxt0IQMgAigCACECA0AgAiIEKAIEQXhxIAFGDQIgA0EddiECIANBAXQhAyAEIAJBBHFqIgcoAhAiAg0ACyAHIAA2AhAgACAENgIYCyAAIAA2AgwgACAANgIIDwsgBCgCCCIBIAA2AgwgBCAANgIIIABBADYCGCAAIAQ2AgwgACABNgIICwu7AQEDfyMAQRBrIgEkAEHoGRAOGkHgFSgCAEUEQEH0FUECNgIAQewVQn83AgBB5BVCgKCAgICABDcCAEG0GUECNgIAIAFBDGoiAkEANgIAIwBBIGsiAEIANwMYIABCADcDECAAQgA3AwhBuBkgACkDCDcCAEHIGSAAKQMYNwIAQcAZIAApAxA3AgAgAgRAQbgZIAIoAgA2AgALQeAVIAFBCGpBcHFB2KrVqgVzNgIAC0HoGRANIAFBEGokAAscACAAIAAQOjYCeCAAQQH+FwJ8IABBAP4XAoABCwQAIwMLGgAgAEEA/kECAEEDRgRAIABB/////wcQDwsLgQEBAX8jAEEgayIIJAACQCAFQQBMDQAgBEEATARAIAVBAnQiAEUNASAGIAdBAnRqQQAgAPwLAAwBCyAIIAU2AhwgCCAEQQV2NgIYIAggAiADajYCDCAIIAYgB0ECdGo2AhQgCCAAIAFBAnRqNgIQQQMgCEEMaiAFEBILIAhBIGokAAsCAAvoBAEGfyMDIgFBAToAKCABIAA2AkAgAUEAOgApIAFBAf4lAnxBAWsiAARAIAFB/ABqIQIDQCACIABEAAAAAAAA8H8QFRogAv4QAgAiAA0ACwsgASgCeBA3AkAgASgCeCIA/hACAEUEQCAAEDkMAQtBjAgQDhogAEGICDYCOCAAQbwIKAIANgI0QbwIIAA2AgAgACgCNCAANgI4QYwIEA0LIwMhAgNAIAIoAkQiAARAIAAoAgQgACgCACACIAAoAgg2AkQRAAAMAQsLAkAjAyIALQAqQQFxRQ0AA0AQKiAAIAAtACpB/gFxOgAqQQAhAgNAIAJBAnQiAygC4BEhBCAAKAJIIANqIgYoAgAhAyAGQQA2AgACQCADRQ0AIARFDQAgBEEdRg0AECAgAyAEEQAAECoLIAJBAWoiAkGAAUcNAAsQICAALQAqQQFxRQ0BIAVBA0kgBUEBaiEFDQALCxAlQQBBAf4eApQNGgJAIAEoAkwiAEUNACAAIAFBzABqIgJGDQADQCAAQQhrKAIAIAEgADYCVCABIAAoAgA2AkwgAEEMayIAQYCAgIAE/kECACEDIAFBADYCVEUgA0EATnFFBEAgAEEBEA8LIAIoAgAiAEUNASAAIAJHDQALCxAtQcwLQcwLKAIAQQFrIgA2AgAgAEUEQEHLC0EAOgAACyABKAIMIgAgASgCCCICNgIIIAIgADYCDCABIAE2AgggASABNgIMECQjBUUEQEEAJANBACQEQQAkBUEBJAYgAUEgaiIAQQJBAf5IAgBBA0YEQCABEAEPCyAAQQD+FwIAIABBARAPDwtBABAEAAsSACAAKAIsIgBBhAEQLiAAEBAL5gQCDH8DewJAIAEgAk4NACACIAFrQQJ0IgMEQCAAKAIIIAFBAnRqQQAgA/wLAAsgACgCDCIKQQBMDQAgACgCCCELIAAoAhAhDCAAKAIAIQ0gACgCBCEOA0AgDiAIQQd0aiEDIA0gCCAMbCABakESbGohBSABIQADQCAFLQABIgZBGHRBgICAgHhxIQQgBS0AACAGQQh0ciIJQf8HcSEHIAlB//8DcSEJAkACQCAGQQJ2QR9xIgYEQCAGQR9HDQEgCUENdCAEckGAgID8B3IhBAwCCyAHRQ0BIARBgICAmARyIAdnIgRBF3RrIAlBCSAEQR9za3RBDnRBgID/A3FyIQQMAQsgBkEXdCAHQQ10ciAEakGAgIDAA2ohBAsgCyAAQQJ0aiIHIAP9AAAAIAX9AAACIg/9DA8PDw8PDw8PDw8PDw8PDw/9Tv0M+Pj4+Pj4+Pj4+Pj4+Pj4+P1uIhD9hwEiEf2nAf36Af3mASAD/QAAECAR/agB/foB/eYB/eQBIAP9AAAgIBD9iAEiEP2nAf36Af3mAf3kASAD/QAAMCAQ/agB/foB/eYB/eQBIAP9AABAIA9BBP1t/Qz4+Pj4+Pj4+Pj4+Pj4+Pj4/W4iD/2HASIQ/acB/foB/eYB/eQBIAP9AABQIBD9qAH9+gH95gH95AEgA/0AAGAgD/2IASIP/acB/foB/eYB/eQBIAP9AABwIA/9qAH9+gH95gH95AEiD/0fACAP/R8BkiAP/R8CkiAP/R8DkiAEvpQgByoCAJI4AgAgBUESaiEFIABBAWoiACACRw0ACyAIQQFqIgggCkcNAAsLCwsAQYQNIwP+FwIACyUBAn9BwAsoAgBBABAYIAAhAQNAIAEoAlggARAxIgEgAEcNAAsLgQEBAX8jAEEgayIIJAACQCAFQQBMDQAgBEEATARAIAVBAnQiAEUNASAGIAdBAnRqQQAgAPwLAAwBCyAIIAU2AhwgCCAEQQV2NgIYIAggAiADajYCDCAIIAYgB0ECdGo2AhQgCCAAIAFBAnRqNgIQQQIgCEEMaiAFEBILIAhBIGokAAs4ACAAIAAoAgAgACgCBCAAKAIIIAAoAgwgACgCEBAKOQMYIAAtACBBAUYEQCAAKAIQEBAgABAQCwulBAIBfwF8IwBBMGsiBSQAIAUgATYCDCAFIAA2AgggBUEANgAsIAVBADYAKSAFQQA6ACggBUIANwMgIAVBADYCHCAFIAM2AhggBSACNgIUIAUjAzYCEAJ8IAQEQCMAQRBrIgMkACADIAVBCGo2AgwgA0EANgIIIANBHDYCBCMAQYABayIAJAAjAEHgAGsiASQAQcQLQRgQKyABQQBB0AD8CwAgAUEbNgJcIAEgA0EEajYCWCABQQA2AlQgAUEANgJQIABBIGoiAiABKAJcNgIAIAIgASgCWDYCBCACIAEoAlQ2AgggAiABKAJQNgIMIAJBEGogAUHQAPwKAAAgAUHgAGokACAAQRY2AhggAEEXNgIUIAAgAjYCHCAAIAI2AhAgACAAKQIUNwMIQZwLQYAMIABBCGoQHQR/IABBMGoiARAOGiAAKAIsRQRAIABByABqIQIDQCACIAEQJiAAKAIsRQ0ACwsgARANIAAoAixBAUYFQQALIQEgAEEgahAyIABBgAFqJAAgA0EQaiQAIAUrAyBEAAAAAAAAAAAgARsMAQtBKBARIgEgBUEIakEo/AoAACABQQE6ACAgASACQQN0IgAQESICNgIQIAIgAyAAEBcjAEEgayIAJAAgACABNgIcIAAgATYCECAAQQA2AhggAEEcNgIUIAAgACkCFDcDCEGcC0GADCAAQQhqEB0aIABBIGokAEQAAAAAAAAAAAsgBUEwaiQAC5QBAQJ/IAEoAgggASgCABEAACMAQSBrIgEkAAJAIAAoAghFBEAgAEEQaiICEA4aIABBATYCDCAAEDMgAhANIABBKGoQKQwBCyAAEDMgACgCECECIAAoAgwgASAANgIcIAEgADYCECABQRQ2AhggAUEVNgIUIAEgASkCFDcDCCACIAFBCGoQHQ0AIAAQFgsgAUEgaiQACxMAIAAoAgQgACgCGBEAACAAEBYL9gIBA38jAyIAKAJIRQRAIABBsA02AkgLAkBBvBEoAgAjAygCGEYNAEGwEUEAQf////8H/kgCAAR/QQoFQbwRIwMoAhg2AgBBAAtBCkcNAEHkACEAA0ACQCAARQ0AQbARKAIARQ0AIABBAWshAEG0ESgCAEUNAQsLQbARQQBB/////wf+SAIABH9BCgVBvBEjAygCGDYCAEEAC0EKRgRAA0ACQEGwESgCACIARQ0AQbQRQQH+HgIAGkGwESAAIABBgICAgHhyIgD+SAIAGkG4ESgCABpBsBEgABAnIQBBtBFBAf4lAgAaIABFDQAgAEEbRw0DC0GwEUEAQf////8H/kgCAAR/QQoFQbwRIwMoAhg2AgBBAAtBCkYNAAsLQbwRIwMoAhg2AgALQdARKAIAIgEhAANAAkAgAEECdCICKALgEUUEQEHACyAANgIAQdARIAA2AgAgAkHgEWpBGjYCAAwBCyAAQQFqQf8AcSIAIAFHDQELCxAgC2oBAX8CQCMDKAJIQcALKAIAQQJ0aigCACIBRQRAIAAgADYCWCAAIAA2AlxBwAsoAgAgABAYDAELIAAgATYCWCAAIAEoAlw2AlwgASAANgJcIAAoAlwgADYCWAsgACAAKAIEIAAoAgARBAALEwAgACgCBCAAKAIUEQAAIAAQFguDDAMNfwF9BHsjAEGAEGsiESQAAkAgCUEATA0AIApBAEwNACAKQQJ0IQ0gCEECdCEPIAYgB0ECdGohECAJQQFrQQNPBEAgCUH8////B3EhFgNAIA1FIhJFBEAgECAMIA9sakEAIA38CwALIBJFBEAgECAPIAxBAXJsakEAIA38CwALIBJFBEAgECAPIAxBAnJsakEAIA38CwALIBJFBEAgECAPIAxBA3JsakEAIA38CwALIAxBBGohDCAOQQRqIg4gFkcNAAsLIAlBA3EiDgRAA0AgDQRAIBAgDCAPbGpBACAN/AsACyAMQQFqIQwgFUEBaiIVIA5HDQALCyALQQBMDQAgCUEBRgRAIApB/P///wdxIQIgAyAEaiEEIAYgB0ECdGohAyAAIAFBAnRqIQYgCkEESSEHQQAhAANAIAQgACAFbGohASAGIABBAnRqKgIAIRlBACEMAkAgB0UEQCAZ/RMhGgNAIAMgDEECdGoiCCAaIAEgDEEBdGr9XQAAIhv9DP9//3//f/9//3//f/9//3/9Tv2pAUEN/asBIhwgHP0MAACADwAAgA8AAIAPAACAD/1OIhz9DAAAgA8AAIAPAACADwAAgA/9N/0MAAAAOAAAADgAAAA4AAAAOP1O/a4BIh39DAAAgDgAAIA4AACAOAAAgDj9rgH9DAAAgLgAAIC4AACAuAAAgLj95AEgHf0MAAAAOAAAADgAAAA4AAAAOP2uASAc/QwAAAAAAAAAAAAAAAAAAAAA/Tf9UiAb/acB/QwAAACAAAAAgAAAAIAAAACA/U79UP3mASAI/QACAP3kAf0LAgAgDEEEaiIMIAJHDQALIAIiDCAKRg0BCwNAIAMgDEECdGoiCCAZIAEgDEEBdGovAAAiCUH//wFxQQ10Ig1BgICAwANBACANQYCAgPwAcSINQYCAgPwARhtqIg5BgICAwANqIA5BgICAxANqvkMAAIC4krwgDRsgCUEQdEGAgICAeHFyvpQgCCoCAJI4AgAgDEEBaiIMIApHDQALCyAAQQFqIgAgC0cNAAsMAQsgAyAEaiEQIAYgB0ECdGohEiAAIAFBAnRqIRUgCiEBQQAhAANAIAAgCkgEQCASIABBAnRqIRYgECAAQQF0aiEYQYAEQQEgASABQQFMGyIDIANBgAROGyIHQfwHcSEDIAdB/AdxIQZBACEEIAFBBEghDQNAIBggBCAFbGohDkEAIQwCQCANRQRAA0AgESAMQQJ0aiAOIAxBAXRq/V0AACIa/Qz/f/9//3//f/9//3//f/9//U79qQFBDf2rASIbIBv9DAAAgA8AAIAPAACADwAAgA/9TiIb/QwAAIAPAACADwAAgA8AAIAP/Tf9DAAAADgAAAA4AAAAOAAAADj9Tv2uASIc/QwAAIA4AACAOAAAgDgAAIA4/a4B/QwAAIC4AACAuAAAgLgAAIC4/eQBIBz9DAAAADgAAAA4AAAAOAAAADj9rgEgG/0MAAAAAAAAAAAAAAAAAAAAAP03/VIgGv2nAf0MAAAAgAAAAIAAAACAAAAAgP1O/VD9CwQAIAxBBGoiDCAGRw0ACyAGIgwgB0YNAQsDQCARIAxBAnRqIA4gDEEBdGovAAAiD0H//wFxQQ10IhNBgICAwANBACATQYCAgPwAcSITQYCAgPwARhtqIhRBgICAwANqIBRBgICAxANqvkMAAIC4krwgExsgD0EQdEGAgICAeHFyNgIAIAxBAWoiDCAHRw0ACwsgFSAEQQJ0aiETQQAhDgNAIBYgCCAObEECdGohDyATIAIgDmxBAnRqKgIAIRlBACEMAkAgDUUEQCAZ/RMhGgNAIA8gDEECdCIUaiIXIBf9AAIAIBEgFGr9AAQAIBr95gH95AH9CwIAIAxBBGoiDCADRw0ACyADIgwgB0YNAQsDQCAPIAxBAnQiFGoiFyAXKgIAIBEgFGoqAgAgGZSSOAIAIAxBAWoiDCAHRw0ACwsgDkEBaiIOIAlHDQALIARBAWoiBCALRw0ACwsgAUGABGshASAAQYAEaiIAIApIDQALCyARQYAQaiQACxkAIABBAf4XAgAgABAoIABBAUEA/kgCABoLBgAgABA3C70HAw1/AX0BeyMAQYAQayISJAACQCAJQQBMDQAgCkEATA0AIApBAnQhDiAIQQJ0IRAgBiAHQQJ0aiERIAlBAWtBA08EQCAJQfz///8HcSEUA0AgDkUiE0UEQCARIAwgEGxqQQAgDvwLAAsgE0UEQCARIBAgDEEBcmxqQQAgDvwLAAsgE0UEQCARIBAgDEECcmxqQQAgDvwLAAsgE0UEQCARIBAgDEEDcmxqQQAgDvwLAAsgDEEEaiEMIA9BBGoiDyAURw0ACwsgCUEDcSIPBEADQCAOBEAgESAMIBBsakEAIA78CwALIAxBAWohDCANQQFqIg0gD0cNAAsLIAtBAEwNACAJQQFGBEAgCkH8////B3EhAiADIARqIQQgBiAHQQJ0aiEDIAAgAUECdGohAUEAIQ0gCkEESSEGA0AgBCAFIA1saiEAIAEgDUECdGoqAgAhGUEAIQwCQCAGRQRAIBn9EyEaA0AgAyAMQQJ0aiIHIBogACAMQQF0av0EAABBEP2rAf3mASAH/QACAP3kAf0LAgAgDEEEaiIMIAJHDQALIAIiDCAKRg0BCwNAIAMgDEECdGoiByAZIAAgDEEBdGovAABBEHS+lCAHKgIAkjgCACAMQQFqIgwgCkcNAAsLIA1BAWoiDSALRw0ACwwBCyADIARqIRAgBiAHQQJ0aiERIAAgAUECdGohE0EAIQAgCiEBA0AgACAKSARAIBEgAEECdGohFCAQIABBAXRqIRdBgARBASABIAFBAUwbIgMgA0GABE4bIgdB/AdxIQMgB0H8B3EhBkEAIQQgAUEESCEOA0AgFyAEIAVsaiENQQAhDAJAIA5FBEADQCASIAxBAnRqIA0gDEEBdGr9BAAAQRD9qwH9CwQAIAxBBGoiDCAGRw0ACyAGIgwgB0YNAQsDQCASIAxBAnRqIA0gDEEBdGovAABBEHQ2AgAgDEEBaiIMIAdHDQALCyATIARBAnRqIRhBACEPA0AgFCAIIA9sQQJ0aiENIBggAiAPbEECdGoqAgAhGUEAIQwCQCAORQRAIBn9EyEaA0AgDSAMQQJ0IhVqIhYgFv0AAgAgEiAVav0ABAAgGv3mAf3kAf0LAgAgDEEEaiIMIANHDQALIAMiDCAHRg0BCwNAIA0gDEECdCIVaiIWIBYqAgAgEiAVaioCACAZlJI4AgAgDEEBaiIMIAdHDQALCyAPQQFqIg8gCUcNAAsgBEEBaiIEIAtHDQALCyABQYAEayEBIABBgARqIgAgCkgNAAsLIBJBgBBqJAALTgEDfyMBIQAjAyICKAJ0IgEEQCACQQA2AnQgASQBIAFBAEEF/AsAIAEPCyMCQQEgABsEQEEBJAJBBRARIQALIAAkASAAQQBBBfwLACAAC84CAQd/A0BBACEAAkADQEGAC/4QAgAgAUcNAUGAC/4QAgAgAUcNAUGAC/4QAgAgAUcNAUGAC/4QAgAgAUcNASAAQQRqIgBBgIDAAEcNAAtB9AkQDhpBAEEB/h4CiAsaIAFBgAv+EAIARgRAA0BBjApB9AkQJkGAC/4QAgAgAUYNAAsLQQBBAf4lAogLGkH0CRANC0GAC/4QAgAhAUH4CigCACECQfAKKAIAIQVB7AooAgAhBkH0CigCACEDIANB/Ar+EAIAIgBKBEAgAkEBdCEHA0AgAyAAQQAgAEHAACADIABrIAdtIgIgAkHAAEwbIABqIgT+SAL8CiICRgR/IAUgACAEIAMgAyAEShsgBhEBAEH8Cv4QAgAFIAILIgBKDQALC0EAQQH+JQKEC0EBRw0AQfQJEA4aQYwL/hACAARAQbwKECkLQfQJEA0MAAsAC3ABAn8jAEEQayIAJAACQCAAQQxqIgEQIw0AIAAoAgwQIkGUC0GUCygCAEEBajYCACABECMNACAAKAIMECJBlAtBlAsoAgBBAWo2AgAgARAjDQAgACgCDBAiQZQLQZQLKAIAQQFqNgIACyAAQRBqJAALuAYDEn8BewF9AkAgACgCDCIKQQBMDQAgASACTg0AIAAoAhAhCyAAKAIIIQwgACgCACENIAAoAgQhDiAAKAIUIgNBBE4EQCADQfz///8HcSEFIANBBGsiD0EEcSERIA9BAnZBAWpB/v///wdxIRIDQCAMIAYgC2xBAnRqIRMgDSADIAZsQQJ0aiEHIAEhBANAIA4gAyAEbEECdGohCUEEIQD9DAAAAAAAAAAAAAAAAAAAAAAhFUEAIQhBACEQIA9BBE8EQANAIAkgAEECdCIUav0AAAAgByAUav0AAAD95gEgCSAIQQJ0Ighq/QAAACAHIAhq/QAAAP3mASAV/eQB/eQBIRUgAEEEaiEIIABBCGohACAQQQJqIhAgEkcNAAsLIBFFBEAgCSAIQQJ0IgBq/QAAACAAIAdq/QAAAP3mASAV/eQBIRULIBX9HwAgFf0fAZIgFf0fApIgFf0fA5IhFiADIAUiAEoEQANAIAkgAEECdCIIaioCACAHIAhqKgIAlCAWkiEWIABBAWoiACADRw0ACwsgEyAEQQJ0aiAWOAIAIARBAWoiBCACRw0ACyAGQQFqIgYgCkcNAAsMAQsgA0EASgRAIANBAUYhBwNAIAwgBCALbEECdGohCSANIAMgBGxBAnRqIQUgASEAA0AgCSAAQQJ0agJ9IA4gACADbEECdGoiBioCACAFKgIAlCIWIAcNABogBioCBCAFKgIElCAWkiIWIANBAkYNABogBioCCCAFKgIIlCAWkgs4AgAgAEEBaiIAIAJHDQALIARBAWoiBCAKRw0ACwwBCyALQQJ0IQUgDCABQQJ0aiEDIAIgAWtBAnQhAUEAIQAgCkEETwRAIApB/P///wdxIQcDQCABRSICRQRAIAMgACAFbGpBACAB/AsACyACRQRAIAMgBSAAQQFybGpBACAB/AsACyACRQRAIAMgBSAAQQJybGpBACAB/AsACyACRQRAIAMgBSAAQQNybGpBACAB/AsACyAAQQRqIQAgBkEEaiIGIAdHDQALCyAKQQNxIgJFDQADQCABBEAgAyAAIAVsakEAIAH8CwALIABBAWohACAEQQFqIgQgAkcNAAsLC84BAgZ/AX0jAEGAAmsiBSQAAkAgASACTg0AIAAoAhAiBkEASgRAIAAoAgAgASAGbEHSAWxqIQQgACgCCCEHIAAoAgQhCANAQwAAAAAhCUEAIQMDQCAEIAggA0EIdGogByADQQJ0aioCACAFEDsgCZIhCSAEQdIBaiEEIANBAWoiAyAGRw0ACyAAKAIMIAFBAnRqIAk4AgAgAUEBaiIBIAJHDQALDAELIAIgAWtBAnQiAkUNACAAKAIMIAFBAnRqQQAgAvwLAAsgBUGAAmokAAsWACAAIAEgAiADIAQgBSAGIAdBDxAeC98BAgt/An0jAEGAAmsiBiQAAkAgASACTg0AIAIgAWtBAnQiAwRAIAAoAgwgAUECdGpBACAD/AsACyAAKAIQIgdBAEwNACAAKAIUIQggACgCACEJIAAoAgghCiAAKAIEIQsDQCALIARBCHRqIQwgCSAEIAhsIAFqQdIBbGohBSAKIARBAnRqKgIAIQ4gASEDA0AgBSAMIA4gBhA7IQ8gACgCDCADQQJ0aiINIA8gDSoCAJI4AgAgBUHSAWohBSADQQFqIgMgAkcNAAsgBEEBaiIEIAdHDQALCyAGQYACaiQACxYAIAAgASACIAMgBCAFIAYgB0EOEB4LqAECBH8BfQJAIAEgAk4NACAAKAIMIgVBAEoEQCAAKAIAIAEgBWxBsAFsaiEDIAAoAgQhBgNAQwAAAAAhB0EAIQQDQCADIAYgBEEKdGoQPCAHkiEHIANBsAFqIQMgBEEBaiIEIAVHDQALIAAoAgggAUECdGogBzgCACABQQFqIgEgAkcNAAsMAQsgAiABa0ECdCICRQ0AIAAoAgggAUECdGpBACAC/AsACwtlAQF/IwBBIGsiCCQAAkAgBEEATA0AIAVBAEwNACAIIAU2AhwgCCAEQQh2NgIYIAggAiADajYCDCAIIAYgB0ECdGo2AhQgCCAAIAFBAnRqNgIQQQ0gCEEMaiAFEBILIAhBIGokAAuvAQEJfwJAIAEgAk4NACACIAFrQQJ0IgMEQCAAKAIIIAFBAnRqQQAgA/wLAAsgACgCDCIGQQBMDQAgACgCECEHIAAoAgAhCCAAKAIEIQkDQCAJIARBCnRqIQogCCAEIAdsIAFqQbABbGohBSABIQMDQCAAKAIIIANBAnRqIgsgCyoCACAFIAoQPJI4AgAgBUGwAWohBSADQQFqIgMgAkcNAAsgBEEBaiIEIAZHDQALCwtlAQF/IwBBIGsiCCQAAkAgBEEATA0AIAVBAEwNACAIIAU2AhwgCCAEQQh2NgIYIAggAiADajYCDCAIIAYgB0ECdGo2AhQgCCAAIAFBAnRqNgIQQQwgCEEMaiAFEBILIAhBIGokAAubAQEBfyMAQSBrIgkkAAJAIAZBAEwNACAHQQBMDQAgCEEATARAIAYgB2wiAEEATA0BIABBAnQiAEUNASAEIAVBAnRqQQAgAPwLAAwBCyAJIAg2AhwgCSAHNgIYIAkgBjYCFCAJIAQgBUECdGo2AhAgCSACIANBAnRqNgIMIAkgACABQQJ0ajYCCEEBIAlBCGogBxASCyAJQSBqJAALugECBX8BfQJAIAEgAk4NACAAKAIQIgVBAEoEQCAAKAIAIAEgBWxBkAFsaiEEIAAoAgghBiAAKAIEIQcDQEMAAAAAIQhBACEDA0AgBCAHIANBCHRqIAYgA0ECdGoqAgAQPSAIkiEIIARBkAFqIQQgA0EBaiIDIAVHDQALIAAoAgwgAUECdGogCDgCACABQQFqIgEgAkcNAAsMAQsgAiABa0ECdCICRQ0AIAAoAgwgAUECdGpBACAC/AsACwsWACAAIAEgAiADIAQgBSAGIAdBCxAeC8sBAgp/An0CQCABIAJODQAgAiABa0ECdCIDBEAgACgCDCABQQJ0akEAIAP8CwALIAAoAhAiBkEATA0AIAAoAhQhByAAKAIAIQggACgCCCEJIAAoAgQhCgNAIAogBEEIdGohCyAIIAQgB2wgAWpBkAFsaiEFIAkgBEECdGoqAgAhDSABIQMDQCAFIAsgDRA9IQ4gACgCDCADQQJ0aiIMIA4gDCoCAJI4AgAgBUGQAWohBSADQQFqIgMgAkcNAAsgBEEBaiIEIAZHDQALCwsWACAAIAEgAiADIAQgBSAGIAdBChAeC7MEAwJ7C38BfQJAIAEgAk4NACAAKAIIIQ0gACgCDCIJQQBMBEAgAiABa0ECdCIARQ0BIA0gAUECdGpBACAA/AsADwsgACgCACABIAlsQSJsaiEKIAlBImwhDiAAKAIEIQ8DQEMAAAAAIRBBACELIAohAANAIA8gC0EHdGohBiAALQABIgdBGHRBgICAgHhxIQUgAC0AACAHQQh0ciIIQf8HcSEMIAhB//8DcSEIAkACQCAHQQJ2QR9xIgcEQCAHQR9HDQEgCEENdCAFckGAgID8B3IhBQwCCyAMRQ0BIAVBgICAmARyIAxnIgVBF3RrIAhBCSAFQR9za3RBDnRBgID/A3FyIQUMAQsgB0EXdCAMQQ10ciAFakGAgIDAA2ohBQsgBv0AAAAgAP0AAAIiA/2HASIE/acB/foB/eYBIAb9AAAQIAT9qAH9+gH95gH95AEgBv0AACAgA/2IASID/acB/foB/eYB/eQBIAb9AAAwIAP9qAH9+gH95gH95AEgBv0AAEAgAP0AABIiA/2HASIE/acB/foB/eYB/eQBIAb9AABQIAT9qAH9+gH95gH95AEgBv0AAGAgA/2IASID/acB/foB/eYB/eQBIAb9AABwIAP9qAH9+gH95gH95AEiA/0fACAD/R8BkiAD/R8CkiAD/R8DkiAFvpQgEJIhECAAQSJqIQAgC0EBaiILIAlHDQALIA0gAUECdGogEDgCACAKIA5qIQogAUEBaiIBIAJHDQALCwuBAQEBfyMAQSBrIggkAAJAIAVBAEwNACAEQQBMBEAgBUECdCIARQ0BIAYgB0ECdGpBACAA/AsADAELIAggBTYCHCAIIARBBXY2AhggCCACIANqNgIMIAggBiAHQQJ0ajYCFCAIIAAgAUECdGo2AhBBCSAIQQxqIAUQEgsgCEEgaiQAC6gEAgJ7DH8CQCABIAJODQAgAiABa0ECdCIFBEAgACgCCCABQQJ0akEAIAX8CwALIAAoAgwiDEEATA0AIAAoAgghDSAAKAIQIQ4gACgCACEPIAAoAgQhEANAIBAgCkEHdGohBSAPIAogDmwgAWpBImxqIQcgASEAA0AgBy0AASIIQRh0QYCAgIB4cSEGIActAAAgCEEIdHIiC0H/B3EhCSALQf//A3EhCwJAAkAgCEECdkEfcSIIBEAgCEEfRw0BIAtBDXQgBnJBgICA/AdyIQYMAgsgCUUNASAGQYCAgJgEciAJZyIGQRd0ayALQQkgBkEfc2t0QQ50QYCA/wNxciEGDAELIAhBF3QgCUENdHIgBmpBgICAwANqIQYLIA0gAEECdGoiCSAF/QAAACAH/QAAAiID/YcBIgT9pwH9+gH95gEgBf0AABAgBP2oAf36Af3mAf3kASAF/QAAICAD/YgBIgP9pwH9+gH95gH95AEgBf0AADAgA/2oAf36Af3mAf3kASAF/QAAQCAH/QAAEiID/YcBIgT9pwH9+gH95gH95AEgBf0AAFAgBP2oAf36Af3mAf3kASAF/QAAYCAD/YgBIgP9pwH9+gH95gH95AEgBf0AAHAgA/2oAf36Af3mAf3kASID/R8AIAP9HwGSIAP9HwKSIAP9HwOSIAa+lCAJKgIAkjgCACAHQSJqIQcgAEEBaiIAIAJHDQALIApBAWoiCiAMRw0ACwsLgQEBAX8jAEEgayIIJAACQCAFQQBMDQAgBEEATARAIAVBAnQiAEUNASAGIAdBAnRqQQAgAPwLAAwBCyAIIAU2AhwgCCAEQQV2NgIYIAggAiADajYCDCAIIAYgB0ECdGo2AhQgCCAAIAFBAnRqNgIQQQggCEEMaiAFEBILIAhBIGokAAuDBAMIfwF9AXsCQCAJQQBMDQAgCkEATA0AIApBAnQhDyAIQQJ0IQ0gBiAHQQJ0aiEOIAlBAWtBA08EQCAJQfz///8HcSERA0AgD0UiEkUEQCAOIAwgDWxqQQAgD/wLAAsgEkUEQCAOIA0gDEEBcmxqQQAgD/wLAAsgEkUEQCAOIA0gDEECcmxqQQAgD/wLAAsgEkUEQCAOIA0gDEEDcmxqQQAgD/wLAAsgDEEEaiEMIBBBBGoiECARRw0ACwsgCUEDcSIRBEADQCAPBEAgDiAMIA1sakEAIA/8CwALIAxBAWohDCATQQFqIhMgEUcNAAsLIAtBAEwNACAKQfz///8HcSERIAMgBEECdGohEiAGIAdBAnRqIRMgACABQQJ0aiEHQQAhBiAKQQRJIQQDQCATIAYgCGxBAnRqIQ0gByACIAZsQQJ0aiEDQQAhEANAIBIgBSAQbEECdGohDiADIBBBAnRqKgIAIRRBACEMAkAgBEUEQCAU/RMhFQNAIA0gDEECdCIBaiIAIAD9AAIAIAEgDmr9AAIAIBX95gH95AH9CwIAIAxBBGoiDCARRw0ACyARIgwgCkYNAQsDQCANIAxBAnQiAWoiACAAKgIAIAEgDmoqAgAgFJSSOAIAIAxBAWoiDCAKRw0ACwsgEEEBaiIQIAtHDQALIAZBAWoiBiAJRw0ACwsLtgkDDn8FewJ9AkAgASACTg0AIAAoAgghDCAAKAIQIgpBAEwEQCACIAFrQQJ0IgBFDQEgDCABQQJ0akEAIAD8CwAPCyAAKAIAIAEgCmxBGGxqIQsgCkEYbCENIAAoAgwhDiAAKAIEIQ8DQEMAAAAAIRZBACEIIAshAANAIAAtAAEiBEEYdEGAgICAeHEhByAALQADQQh0IgkgAC0AAnIhAyAALQAAIARBCHRyIgZB/wdxIQUgBkH//wNxIQYgDiAIQQJ0agJAAkAgBEECdkEfcSIEBEAgBEEfRw0BIAZBDXQgB3JBgICA/AdyIQcMAgsgBUUNASAHQYCAgJgEciAFZyIFQRd0ayAGQQkgBUEfc2t0QQ50QYCA/wNxciEHDAELIARBF3QgBUENdHIgB2pBgICAwANqIQcLIA8gCEEHdGohBSoCACADQf8HcSEGIAlBEHRBgICAgHhxIQQCQAJAIANBCnZBH3EiCQRAIAlBH0cNASADQQ10IARyQYCAgPwHciEEDAILIAZFDQEgBEGAgICYBHIgBmciBEEXdGsgA0EJIARBH3NrdEEOdEGAgP8DcXIhBAwBCyAJQRd0IAZBDXRyIARqQYCAgMADaiEECyAEvpQgFpIgBf0AAjAgAP1cABT9iQH9qQEiEf0MDwAAAA8AAAAPAAAADwAAAP1OIAAoAAQiA0EIdv0RIANBCXb9HAEgA0EKdv0cAiADQQt2/RwDIhL9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAX9AAIgIAD9XAAQ/YkB/akBIhT9DA8AAAAPAAAADwAAAA8AAAD9TiASQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAX9AAIQIAD9XAAM/YkB/akBIhL9DA8AAAAPAAAADwAAAA8AAAD9TiAD/REgA0EBdv0cASADQQJ2/RwCIANBA3b9HAMiE/0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBf0AAgAgAP1cAAj9iQH9qQEiFf0MDwAAAA8AAAAPAAAADwAAAP1OIBNBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBf0AAkAgA0EQdv0RIANBEXb9HAEgA0ESdv0cAiADQRN2/RwDIhNBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBVBBP2tAf1Q/foB/eYB/eQB/eQBIAX9AAJQIBP9DBAAAAAQAAAAEAAAABAAAAD9TiASQQT9rQH9UP36Af3mAf3kAf3kASAF/QACYCADQRh2/REgA0EZdv0cASADQRp2/RwCIANBG3b9HAMiEkEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gFEEE/a0B/VD9+gH95gH95AH95AEgBf0AAnAgEv0MEAAAABAAAAAQAAAAEAAAAP1OIBFBBP2tAf1Q/foB/eYB/eQBIhEgESAR/Q0EBQYHAAECAwwNDg8AAQID/eQBIhEgESAR/Q0ICQoLAAECAwABAgMAAQID/eQB/R8AIAe+lJIhFiAAQRhqIQAgCEEBaiIIIApHDQALIAwgAUECdGogFjgCACALIA1qIQsgAUEBaiIBIAJHDQALCwsWACAAIAEgAiADIAQgBSAGIAdBBxAfC68JAhB/BXsCQCABIAJODQAgAiABa0ECdCIJBEAgACgCCCABQQJ0akEAIAn8CwALIAAoAhAiC0EATA0AIAAoAgghDCAAKAIMIQ0gACgCFCEOIAAoAgAhDyAAKAIEIRADQCANIApBAnRqIREgECAKQQd0aiEHIA8gCiAObCABakEYbGohBCABIQkDQCAELQABIgVBGHRBgICAgHhxIQYgBC0AA0EIdCISIAQtAAJyIQAgBC0AACAFQQh0ciIIQf8HcSEDIAhB//8DcSEIAkACQCAFQQJ2QR9xIgUEQCAFQR9HDQEgCEENdCAGckGAgID8B3IhBgwCCyADRQ0BIAZBgICAmARyIANnIgZBF3RrIAhBCSAGQR9za3RBDnRBgID/A3FyIQYMAQsgBUEXdCADQQ10ciAGakGAgIDAA2ohBgsgAEH/B3EhBSASQRB0QYCAgIB4cSEDAkACQCAAQQp2QR9xIggEQCAIQR9HDQEgAEENdCADckGAgID8B3IhAwwCCyAFRQ0BIANBgICAmARyIAVnIgNBF3RrIABBCSADQR9za3RBDnRBgID/A3FyIQMMAQsgCEEXdCAFQQ10ciADakGAgIDAA2ohAwsgDCAJQQJ0aiIFIAf9AAIwIAT9XAAU/YkB/akBIhP9DA8AAAAPAAAADwAAAA8AAAD9TiAEKAAEIgBBCHb9ESAAQQl2/RwBIABBCnb9HAIgAEELdv0cAyIU/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAH/QACICAE/VwAEP2JAf2pASIW/QwPAAAADwAAAA8AAAAPAAAA/U4gFEEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAH/QACECAE/VwADP2JAf2pASIU/QwPAAAADwAAAA8AAAAPAAAA/U4gAP0RIABBAXb9HAEgAEECdv0cAiAAQQN2/RwDIhX9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAf9AAIAIAT9XAAI/YkB/akBIhf9DA8AAAAPAAAADwAAAA8AAAD9TiAVQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAf9AAJAIABBEHb9ESAAQRF2/RwBIABBEnb9HAIgAEETdv0cAyIVQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAXQQT9rQH9UP36Af3mAf3kAf3kASAH/QACUCAV/QwQAAAAEAAAABAAAAAQAAAA/U4gFEEE/a0B/VD9+gH95gH95AH95AEgB/0AAmAgAEEYdv0RIABBGXb9HAEgAEEadv0cAiAAQRt2/RwDIhRBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBZBBP2tAf1Q/foB/eYB/eQB/eQBIAf9AAJwIBT9DBAAAAAQAAAAEAAAABAAAAD9TiATQQT9rQH9UP36Af3mAf3kASITIBMgE/0NBAUGBwABAgMMDQ4PAAECA/3kASITIBMgE/0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAGvpQgESoCACADvpSSIAUqAgCSOAIAIARBGGohBCAJQQFqIgkgAkcNAAsgCkEBaiIKIAtHDQALCwsWACAAIAEgAiADIAQgBSAGIAdBBhAfC6AIAwx/BXsCfQJAIAEgAk4NACAAKAIIIQsgACgCECIJQQBMBEAgAiABa0ECdCIARQ0BIAsgAUECdGpBACAA/AsADwsgACgCACABIAlsQRZsaiEKIAlBFmwhDCAAKAIMIQ0gACgCBCEOA0BDAAAAACEUQQAhByAKIQADQCAOIAdBB3RqIQQgAC0AASIGQRh0QYCAgIB4cSEFIAAtAAAgBkEIdHIiCEH/B3EhAyAIQf//A3EhCCANIAdBAnRqKgIAIRUCQAJAIAZBAnZBH3EiBgRAIAZBH0cNASAIQQ10IAVyQYCAgPwHciEFDAILIANFDQEgBUGAgICYBHIgA2ciA0EXdGsgCEEJIANBH3NrdEEOdEGAgP8DcXIhBQwBCyAGQRd0IANBDXRyIAVqQYCAgMADaiEFCyAE/QACMCAA/VwAEv2JAf2pASIP/QwPAAAADwAAAA8AAAAPAAAA/U4gACgAAiIDQQh2/REgA0EJdv0cASADQQp2/RwCIANBC3b9HAMiEP0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBP0AAiAgAP1cAA79iQH9qQEiEv0MDwAAAA8AAAAPAAAADwAAAP1OIBBBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gEgBP0AAhAgAP1cAAr9iQH9qQEiEP0MDwAAAA8AAAAPAAAADwAAAP1OIAP9ESADQQF2/RwBIANBAnb9HAIgA0EDdv0cAyIR/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAE/QACACAA/VwABv2JAf2pASIT/QwPAAAADwAAAA8AAAAPAAAA/U4gEUEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAE/QACQCADQRB2/REgA0ERdv0cASADQRJ2/RwCIANBE3b9HAMiEUEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U4gE0EE/a0B/VD9+gH95gH95AH95AEgBP0AAlAgEf0MEAAAABAAAAAQAAAAEAAAAP1OIBBBBP2tAf1Q/foB/eYB/eQB/eQBIAT9AAJgIANBGHb9ESADQRl2/RwBIANBGnb9HAIgA0Ebdv0cAyIQQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiASQQT9rQH9UP36Af3mAf3kAf3kASAE/QACcCAQ/QwQAAAAEAAAABAAAAAQAAAA/U4gD0EE/a0B/VD9+gH95gH95AEiDyAPIA/9DQQFBgcAAQIDDA0ODwABAgP95AEiDyAPIA/9DQgJCgsAAQIDAAECAwABAgP95AH9HwAgFUMAAIDBlJIgBb6UIBSSIRQgAEEWaiEAIAdBAWoiByAJRw0ACyALIAFBAnRqIBQ4AgAgCiAMaiEKIAFBAWoiASACRw0ACwsLFgAgACABIAIgAyAEIAUgBiAHQQUQHwuVCAIOfwV7AkAgASACTg0AIAIgAWtBAnQiAwRAIAAoAgggAUECdGpBACAD/AsACyAAKAIQIgpBAEwNACAAKAIIIQsgACgCDCEMIAAoAhQhDSAAKAIAIQ4gACgCBCEPA0AgDCAHQQJ0aiEQIA8gB0EHdGohBSAOIAcgDWwgAWpBFmxqIQQgASEAA0AgBC0AASIIQRh0QYCAgIB4cSEGIAQtAAAgCEEIdHIiCUH/B3EhAyAJQf//A3EhCQJAAkAgCEECdkEfcSIIBEAgCEEfRw0BIAlBDXQgBnJBgICA/AdyIQYMAgsgA0UNASAGQYCAgJgEciADZyIDQRd0ayAJQQkgA0Efc2t0QQ50QYCA/wNxciEGDAELIAhBF3QgA0ENdHIgBmpBgICAwANqIQYLIAsgAEECdGoiAyADKgIAIAX9AAIwIAT9XAAS/YkB/akBIhH9DA8AAAAPAAAADwAAAA8AAAD9TiAEKAACIgNBCHb9ESADQQl2/RwBIANBCnb9HAIgA0ELdv0cAyIS/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAF/QACICAE/VwADv2JAf2pASIU/QwPAAAADwAAAA8AAAAPAAAA/U4gEkEE/asB/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mASAF/QACECAE/VwACv2JAf2pASIS/QwPAAAADwAAAA8AAAAPAAAA/U4gA/0RIANBAXb9HAEgA0ECdv0cAiADQQN2/RwDIhP9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAX9AAIAIAT9XAAG/YkB/akBIhX9DA8AAAAPAAAADwAAAA8AAAD9TiATQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYBIAX9AAJAIANBEHb9ESADQRF2/RwBIANBEnb9HAIgA0ETdv0cAyITQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9TiAVQQT9rQH9UP36Af3mAf3kAf3kASAF/QACUCAT/QwQAAAAEAAAABAAAAAQAAAA/U4gEkEE/a0B/VD9+gH95gH95AH95AEgBf0AAmAgA0EYdv0RIANBGXb9HAEgA0Eadv0cAiADQRt2/RwDIhJBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIBRBBP2tAf1Q/foB/eYB/eQB/eQBIAX9AAJwIBL9DBAAAAAQAAAAEAAAABAAAAD9TiARQQT9rQH9UP36Af3mAf3kASIRIBEgEf0NBAUGBwABAgMMDQ4PAAECA/3kASIRIBEgEf0NCAkKCwABAgMAAQIDAAECA/3kAf0fACAQKgIAQwAAgMGUkiAGvpSSOAIAIARBFmohBCAAQQFqIgAgAkcNAAsgB0EBaiIHIApHDQALCwsEACMACxAAIwAgAGtBcHEiACQAIAALBgAgACQACycAIAAkAyABJAQgAiQFIAMkBgJAIAJFDQAgBEUNAEHECCAENgIACwsKACAAJAggASQHCxYAIAAgASACIAMgBCAFIAYgB0EEEB8LBABCAAvwAgEHfyMAQSBrIgMkACADIAAoAhwiBDYCECAAKAIUIQUgAyACNgIcIAMgATYCGCADIAUgBGsiATYCFCABIAJqIQVBAiEHAn8CQAJAAkAgACgCPCADQRBqIgFBAiADQQxqEAIiBAR/IwEgBDYCAEF/BUEACwRAIAEhBAwBCwNAIAUgAygCDCIGRg0CIAZBAEgEQCABIQQMBAsgAUEIQQAgBiABKAIEIghLIgkbaiIEIAYgCEEAIAkbayIIIAQoAgBqNgIAIAFBDEEEIAkbaiIBIAEoAgAgCGs2AgAgBSAGayEFIAAoAjwgBCIBIAcgCWsiByADQQxqEAIiBgR/IwEgBjYCAEF/BUEAC0UNAAsLIAVBf0cNAQsgACAAKAIsIgE2AhwgACABNgIUIAAgASAAKAIwajYCECACDAELIABBADYCHCAAQgA3AxAgACAAKAIAQSByNgIAQQAgB0ECRg0AGiACIAQoAgRrCyADQSBqJAALBABBAAsgAQF/IwMoAngiAEEB/hcCACAAECggAEEBQQD+SAIAGgvxBAMLfwN7AX0CQCABIAJODQAgACgCCCELIAAoAgwiB0EATARAIAIgAWtBAnQiAEUNASALIAFBAnRqQQAgAPwLAA8LIAAoAgAgASAHbEESbGohCCAHQRJsIQwgACgCBCENA0BDAAAAACERQQAhCSAIIQADQCANIAlBB3RqIQQgAC0AASIFQRh0QYCAgIB4cSEDIAAtAAAgBUEIdHIiBkH/B3EhCiAGQf//A3EhBgJAAkAgBUECdkEfcSIFBEAgBUEfRw0BIAZBDXQgA3JBgICA/AdyIQMMAgsgCkUNASADQYCAgJgEciAKZyIDQRd0ayAGQQkgA0Efc2t0QQ50QYCA/wNxciEDDAELIAVBF3QgCkENdHIgA2pBgICAwANqIQMLIAT9AAAAIAD9AAACIg79DA8PDw8PDw8PDw8PDw8PDw/9Tv0M+Pj4+Pj4+Pj4+Pj4+Pj4+P1uIg/9hwEiEP2nAf36Af3mASAE/QAAECAQ/agB/foB/eYB/eQBIAT9AAAgIA/9iAEiD/2nAf36Af3mAf3kASAE/QAAMCAP/agB/foB/eYB/eQBIAT9AABAIA5BBP1t/Qz4+Pj4+Pj4+Pj4+Pj4+Pj4/W4iDv2HASIP/acB/foB/eYB/eQBIAT9AABQIA/9qAH9+gH95gH95AEgBP0AAGAgDv2IASIO/acB/foB/eYB/eQBIAT9AABwIA79qAH9+gH95gH95AEiDv0fACAO/R8BkiAO/R8CkiAO/R8DkiADvpQgEZIhESAAQRJqIQAgCUEBaiIJIAdHDQALIAsgAUECdGogETgCACAIIAxqIQggAUEBaiIBIAJHDQALCwuRAQACQAJAAkBBiCJBAEEB/kgCAA4CAAECC0GACCQBQYAIQQBBBfwLACMJBEAAC0GICEEAQTT8CwBBvAhBAEHlAPwIAABBoQlBAEE//AsAQeAJQQBBCPwIAQBB8AlBAEGYGPwLAEGIIkEC/hcCAEGIIkF//gACABoMAQtBiCJBAUJ//gECABoLQQEkCfwJAPwJAQt1AEGQogQkCEGQIiQHQaAMQQI2AgBBgAxBgAw2AgBBzAxBzAw2AgBB4AxB6As2AgBBmAxBKjYCAEHIDEGwDTYCAEGMDEGADDYCAEGIDEGADDYCAEGADBAJQbQMIwg2AgBBuAwjCCMHazYCAEGADBBAQYAMEAgLC3ICAWUIBAAACAQAAAAAAQAAAgAAAAAAAAUAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAhAAAACA0AAAAEAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAD/////CgEIUAQAABARAQA=" + const val ST_WASM: String = "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" + const val MT_MJS: String = "YXN5bmMgZnVuY3Rpb24gY3JlYXRlU2thaW5ldEtlcm5lbHMobW9kdWxlQXJnPXt9KXt2YXIgbW9kdWxlUnRuO3ZhciBNb2R1bGU9bW9kdWxlQXJnO3ZhciBFTlZJUk9OTUVOVF9JU19XRUI9dHlwZW9mIHdpbmRvdz09Im9iamVjdCI7dmFyIEVOVklST05NRU5UX0lTX1dPUktFUj10eXBlb2YgV29ya2VyR2xvYmFsU2NvcGUhPSJ1bmRlZmluZWQiO3ZhciBFTlZJUk9OTUVOVF9JU19OT0RFPXR5cGVvZiBwcm9jZXNzPT0ib2JqZWN0IiYmcHJvY2Vzcy52ZXJzaW9ucz8ubm9kZSYmcHJvY2Vzcy50eXBlIT0icmVuZGVyZXIiO3ZhciBFTlZJUk9OTUVOVF9JU19QVEhSRUFEPUVOVklST05NRU5UX0lTX1dPUktFUiYmc2VsZi5uYW1lPy5zdGFydHNXaXRoKCJlbS1wdGhyZWFkIik7aWYoRU5WSVJPTk1FTlRfSVNfTk9ERSl7Y29uc3R7Y3JlYXRlUmVxdWlyZX09YXdhaXQgaW1wb3J0KCJtb2R1bGUiKTt2YXIgcmVxdWlyZT1jcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybC5zdGFydHNXaXRoKCJmaWxlOiIpP2ltcG9ydC5tZXRhLnVybDpwcm9jZXNzLmN3ZCgpKyIvIik7dmFyIHdvcmtlcl90aHJlYWRzPXJlcXVpcmUoIndvcmtlcl90aHJlYWRzIik7Z2xvYmFsLldvcmtlcj13b3JrZXJfdGhyZWFkcy5Xb3JrZXI7RU5WSVJPTk1FTlRfSVNfV09SS0VSPSF3b3JrZXJfdGhyZWFkcy5pc01haW5UaHJlYWQ7RU5WSVJPTk1FTlRfSVNfUFRIUkVBRD1FTlZJUk9OTUVOVF9JU19XT1JLRVImJndvcmtlcl90aHJlYWRzWyJ3b3JrZXJEYXRhIl09PSJlbS1wdGhyZWFkIn12YXIgYXJndW1lbnRzXz1bXTt2YXIgdGhpc1Byb2dyYW09Ii4vdGhpcy5wcm9ncmFtIjt2YXIgcXVpdF89KHN0YXR1cyx0b1Rocm93KT0+e3Rocm93IHRvVGhyb3d9O3ZhciBfc2NyaXB0TmFtZT1pbXBvcnQubWV0YS51cmw7dmFyIHNjcmlwdERpcmVjdG9yeT0iIjtmdW5jdGlvbiBsb2NhdGVGaWxlKHBhdGgpe2lmKE1vZHVsZVsibG9jYXRlRmlsZSJdKXtyZXR1cm4gTW9kdWxlWyJsb2NhdGVGaWxlIl0ocGF0aCxzY3JpcHREaXJlY3RvcnkpfXJldHVybiBzY3JpcHREaXJlY3RvcnkrcGF0aH12YXIgcmVhZEFzeW5jLHJlYWRCaW5hcnk7aWYoRU5WSVJPTk1FTlRfSVNfTk9ERSl7dmFyIGZzPXJlcXVpcmUoImZzIik7aWYoX3NjcmlwdE5hbWUuc3RhcnRzV2l0aCgiZmlsZToiKSl7c2NyaXB0RGlyZWN0b3J5PXJlcXVpcmUoInBhdGgiKS5kaXJuYW1lKHJlcXVpcmUoInVybCIpLmZpbGVVUkxUb1BhdGgoX3NjcmlwdE5hbWUpKSsiLyJ9cmVhZEJpbmFyeT1maWxlbmFtZT0+e2ZpbGVuYW1lPWlzRmlsZVVSSShmaWxlbmFtZSk/bmV3IFVSTChmaWxlbmFtZSk6ZmlsZW5hbWU7dmFyIHJldD1mcy5yZWFkRmlsZVN5bmMoZmlsZW5hbWUpO3JldHVybiByZXR9O3JlYWRBc3luYz1hc3luYyhmaWxlbmFtZSxiaW5hcnk9dHJ1ZSk9PntmaWxlbmFtZT1pc0ZpbGVVUkkoZmlsZW5hbWUpP25ldyBVUkwoZmlsZW5hbWUpOmZpbGVuYW1lO3ZhciByZXQ9ZnMucmVhZEZpbGVTeW5jKGZpbGVuYW1lLGJpbmFyeT91bmRlZmluZWQ6InV0ZjgiKTtyZXR1cm4gcmV0fTtpZihwcm9jZXNzLmFyZ3YubGVuZ3RoPjEpe3RoaXNQcm9ncmFtPXByb2Nlc3MuYXJndlsxXS5yZXBsYWNlKC9cXC9nLCIvIil9YXJndW1lbnRzXz1wcm9jZXNzLmFyZ3Yuc2xpY2UoMik7cXVpdF89KHN0YXR1cyx0b1Rocm93KT0+e3Byb2Nlc3MuZXhpdENvZGU9c3RhdHVzO3Rocm93IHRvVGhyb3d9fWVsc2UgaWYoRU5WSVJPTk1FTlRfSVNfV0VCfHxFTlZJUk9OTUVOVF9JU19XT1JLRVIpe3RyeXtzY3JpcHREaXJlY3Rvcnk9bmV3IFVSTCgiLiIsX3NjcmlwdE5hbWUpLmhyZWZ9Y2F0Y2h7fWlmKCFFTlZJUk9OTUVOVF9JU19OT0RFKXtpZihFTlZJUk9OTUVOVF9JU19XT1JLRVIpe3JlYWRCaW5hcnk9dXJsPT57dmFyIHhocj1uZXcgWE1MSHR0cFJlcXVlc3Q7eGhyLm9wZW4oIkdFVCIsdXJsLGZhbHNlKTt4aHIucmVzcG9uc2VUeXBlPSJhcnJheWJ1ZmZlciI7eGhyLnNlbmQobnVsbCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KHhoci5yZXNwb25zZSl9fXJlYWRBc3luYz1hc3luYyB1cmw9Pnt2YXIgcmVzcG9uc2U9YXdhaXQgZmV0Y2godXJsLHtjcmVkZW50aWFsczoic2FtZS1vcmlnaW4ifSk7aWYocmVzcG9uc2Uub2spe3JldHVybiByZXNwb25zZS5hcnJheUJ1ZmZlcigpfXRocm93IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXMrIiA6ICIrcmVzcG9uc2UudXJsKX19fWVsc2V7fXZhciBkZWZhdWx0UHJpbnQ9Y29uc29sZS5sb2cuYmluZChjb25zb2xlKTt2YXIgZGVmYXVsdFByaW50RXJyPWNvbnNvbGUuZXJyb3IuYmluZChjb25zb2xlKTtpZihFTlZJUk9OTUVOVF9JU19OT0RFKXt2YXIgdXRpbHM9cmVxdWlyZSgidXRpbCIpO3ZhciBzdHJpbmdpZnk9YT0+dHlwZW9mIGE9PSJvYmplY3QiP3V0aWxzLmluc3BlY3QoYSk6YTtkZWZhdWx0UHJpbnQ9KC4uLmFyZ3MpPT5mcy53cml0ZVN5bmMoMSxhcmdzLm1hcChzdHJpbmdpZnkpLmpvaW4oIiAiKSsiXG4iKTtkZWZhdWx0UHJpbnRFcnI9KC4uLmFyZ3MpPT5mcy53cml0ZVN5bmMoMixhcmdzLm1hcChzdHJpbmdpZnkpLmpvaW4oIiAiKSsiXG4iKX12YXIgb3V0PWRlZmF1bHRQcmludDt2YXIgZXJyPWRlZmF1bHRQcmludEVycjt2YXIgd2FzbUJpbmFyeTt2YXIgd2FzbU1vZHVsZTt2YXIgQUJPUlQ9ZmFsc2U7dmFyIEVYSVRTVEFUVVM7dmFyIGlzRmlsZVVSST1maWxlbmFtZT0+ZmlsZW5hbWUuc3RhcnRzV2l0aCgiZmlsZTovLyIpO2Z1bmN0aW9uIGdyb3dNZW1WaWV3cygpe2lmKHdhc21NZW1vcnkuYnVmZmVyIT1IRUFQOC5idWZmZXIpe3VwZGF0ZU1lbW9yeVZpZXdzKCl9fXZhciByZWFkeVByb21pc2VSZXNvbHZlLHJlYWR5UHJvbWlzZVJlamVjdDtpZihFTlZJUk9OTUVOVF9JU19OT0RFJiZFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt2YXIgcGFyZW50UG9ydD13b3JrZXJfdGhyZWFkc1sicGFyZW50UG9ydCJdO3BhcmVudFBvcnQub24oIm1lc3NhZ2UiLG1zZz0+Z2xvYmFsLm9ubWVzc2FnZT8uKHtkYXRhOm1zZ30pKTtPYmplY3QuYXNzaWduKGdsb2JhbFRoaXMse3NlbGY6Z2xvYmFsLHBvc3RNZXNzYWdlOm1zZz0+cGFyZW50UG9ydFsicG9zdE1lc3NhZ2UiXShtc2cpfSk7cHJvY2Vzcy5vbigidW5jYXVnaHRFeGNlcHRpb24iLGVycj0+e3Bvc3RNZXNzYWdlKHtjbWQ6InVuY2F1Z2h0RXhjZXB0aW9uIixlcnJvcjplcnJ9KTtwcm9jZXNzLmV4aXQoMSl9KX12YXIgc3RhcnRXb3JrZXI7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7dmFyIGluaXRpYWxpemVkSlM9ZmFsc2U7c2VsZi5vbnVuaGFuZGxlZHJlamVjdGlvbj1lPT57dGhyb3cgZS5yZWFzb258fGV9O2Z1bmN0aW9uIGhhbmRsZU1lc3NhZ2UoZSl7dHJ5e3ZhciBtc2dEYXRhPWVbImRhdGEiXTt2YXIgY21kPW1zZ0RhdGEuY21kO2lmKGNtZD09PSJsb2FkIil7bGV0IG1lc3NhZ2VRdWV1ZT1bXTtzZWxmLm9ubWVzc2FnZT1lPT5tZXNzYWdlUXVldWUucHVzaChlKTtzdGFydFdvcmtlcj0oKT0+e3Bvc3RNZXNzYWdlKHtjbWQ6ImxvYWRlZCJ9KTtmb3IobGV0IG1zZyBvZiBtZXNzYWdlUXVldWUpe2hhbmRsZU1lc3NhZ2UobXNnKX1zZWxmLm9ubWVzc2FnZT1oYW5kbGVNZXNzYWdlfTtmb3IoY29uc3QgaGFuZGxlciBvZiBtc2dEYXRhLmhhbmRsZXJzKXtpZighTW9kdWxlW2hhbmRsZXJdfHxNb2R1bGVbaGFuZGxlcl0ucHJveHkpe01vZHVsZVtoYW5kbGVyXT0oLi4uYXJncyk9Pntwb3N0TWVzc2FnZSh7Y21kOiJjYWxsSGFuZGxlciIsaGFuZGxlcixhcmdzfSl9O2lmKGhhbmRsZXI9PSJwcmludCIpb3V0PU1vZHVsZVtoYW5kbGVyXTtpZihoYW5kbGVyPT0icHJpbnRFcnIiKWVycj1Nb2R1bGVbaGFuZGxlcl19fXdhc21NZW1vcnk9bXNnRGF0YS53YXNtTWVtb3J5O3VwZGF0ZU1lbW9yeVZpZXdzKCk7d2FzbU1vZHVsZT1tc2dEYXRhLndhc21Nb2R1bGU7Y3JlYXRlV2FzbSgpO3J1bigpfWVsc2UgaWYoY21kPT09InJ1biIpe2VzdGFibGlzaFN0YWNrU3BhY2UobXNnRGF0YS5wdGhyZWFkX3B0cik7X19lbXNjcmlwdGVuX3RocmVhZF9pbml0KG1zZ0RhdGEucHRocmVhZF9wdHIsMCwwLDEsMCwwKTtQVGhyZWFkLnRocmVhZEluaXRUTFMoKTtfX2Vtc2NyaXB0ZW5fdGhyZWFkX21haWxib3hfYXdhaXQobXNnRGF0YS5wdGhyZWFkX3B0cik7aWYoIWluaXRpYWxpemVkSlMpe2luaXRpYWxpemVkSlM9dHJ1ZX10cnl7aW52b2tlRW50cnlQb2ludChtc2dEYXRhLnN0YXJ0X3JvdXRpbmUsbXNnRGF0YS5hcmcpfWNhdGNoKGV4KXtpZihleCE9InVud2luZCIpe3Rocm93IGV4fX19ZWxzZSBpZihtc2dEYXRhLnRhcmdldD09PSJzZXRpbW1lZGlhdGUiKXt9ZWxzZSBpZihjbWQ9PT0iY2hlY2tNYWlsYm94Iil7aWYoaW5pdGlhbGl6ZWRKUyl7Y2hlY2tNYWlsYm94KCl9fWVsc2UgaWYoY21kKXtlcnIoYHdvcmtlcjogcmVjZWl2ZWQgdW5rbm93biBjb21tYW5kICR7Y21kfWApO2Vycihtc2dEYXRhKX19Y2F0Y2goZXgpe19fZW1zY3JpcHRlbl90aHJlYWRfY3Jhc2hlZCgpO3Rocm93IGV4fX1zZWxmLm9ubWVzc2FnZT1oYW5kbGVNZXNzYWdlfXZhciB3YXNtTWVtb3J5O3ZhciBIRUFQOCxIRUFQVTgsSEVBUDE2LEhFQVBVMTYsSEVBUDMyLEhFQVBVMzIsSEVBUEYzMixIRUFQRjY0O3ZhciBIRUFQNjQsSEVBUFU2NDt2YXIgcnVudGltZUluaXRpYWxpemVkPWZhbHNlO2Z1bmN0aW9uIHVwZGF0ZU1lbW9yeVZpZXdzKCl7dmFyIGI9d2FzbU1lbW9yeS5idWZmZXI7SEVBUDg9bmV3IEludDhBcnJheShiKTtIRUFQMTY9bmV3IEludDE2QXJyYXkoYik7SEVBUFU4PW5ldyBVaW50OEFycmF5KGIpO0hFQVBVMTY9bmV3IFVpbnQxNkFycmF5KGIpO0hFQVAzMj1uZXcgSW50MzJBcnJheShiKTtIRUFQVTMyPW5ldyBVaW50MzJBcnJheShiKTtIRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYik7SEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGIpO0hFQVA2ND1uZXcgQmlnSW50NjRBcnJheShiKTtIRUFQVTY0PW5ldyBCaWdVaW50NjRBcnJheShiKX1mdW5jdGlvbiBpbml0TWVtb3J5KCl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7cmV0dXJufWlmKE1vZHVsZVsid2FzbU1lbW9yeSJdKXt3YXNtTWVtb3J5PU1vZHVsZVsid2FzbU1lbW9yeSJdfWVsc2V7dmFyIElOSVRJQUxfTUVNT1JZPU1vZHVsZVsiSU5JVElBTF9NRU1PUlkiXXx8NjcxMDg4NjQ7d2FzbU1lbW9yeT1uZXcgV2ViQXNzZW1ibHkuTWVtb3J5KHtpbml0aWFsOklOSVRJQUxfTUVNT1JZLzY1NTM2LG1heGltdW06NjU1MzYsc2hhcmVkOnRydWV9KX11cGRhdGVNZW1vcnlWaWV3cygpfWZ1bmN0aW9uIHByZVJ1bigpe2lmKE1vZHVsZVsicHJlUnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInByZVJ1biJdPT0iZnVuY3Rpb24iKU1vZHVsZVsicHJlUnVuIl09W01vZHVsZVsicHJlUnVuIl1dO3doaWxlKE1vZHVsZVsicHJlUnVuIl0ubGVuZ3RoKXthZGRPblByZVJ1bihNb2R1bGVbInByZVJ1biJdLnNoaWZ0KCkpfX1jYWxsUnVudGltZUNhbGxiYWNrcyhvblByZVJ1bnMpfWZ1bmN0aW9uIGluaXRSdW50aW1lKCl7cnVudGltZUluaXRpYWxpemVkPXRydWU7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRClyZXR1cm4gc3RhcnRXb3JrZXIoKTt3YXNtRXhwb3J0c1sibyJdKCl9ZnVuY3Rpb24gcG9zdFJ1bigpe2lmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpe3JldHVybn1pZihNb2R1bGVbInBvc3RSdW4iXSl7aWYodHlwZW9mIE1vZHVsZVsicG9zdFJ1biJdPT0iZnVuY3Rpb24iKU1vZHVsZVsicG9zdFJ1biJdPVtNb2R1bGVbInBvc3RSdW4iXV07d2hpbGUoTW9kdWxlWyJwb3N0UnVuIl0ubGVuZ3RoKXthZGRPblBvc3RSdW4oTW9kdWxlWyJwb3N0UnVuIl0uc2hpZnQoKSl9fWNhbGxSdW50aW1lQ2FsbGJhY2tzKG9uUG9zdFJ1bnMpfWZ1bmN0aW9uIGFib3J0KHdoYXQpe01vZHVsZVsib25BYm9ydCJdPy4od2hhdCk7d2hhdD0iQWJvcnRlZCgiK3doYXQrIikiO2Vycih3aGF0KTtBQk9SVD10cnVlO3doYXQrPSIuIEJ1aWxkIHdpdGggLXNBU1NFUlRJT05TIGZvciBtb3JlIGluZm8uIjt2YXIgZT1uZXcgV2ViQXNzZW1ibHkuUnVudGltZUVycm9yKHdoYXQpO3JlYWR5UHJvbWlzZVJlamVjdD8uKGUpO3Rocm93IGV9dmFyIHdhc21CaW5hcnlGaWxlO2Z1bmN0aW9uIGZpbmRXYXNtQmluYXJ5KCl7aWYoTW9kdWxlWyJsb2NhdGVGaWxlIl0pe3JldHVybiBsb2NhdGVGaWxlKCJza2FpbmV0X2tlcm5lbHNfbXQud2FzbSIpfXRyeXtyZXR1cm4gbmV3IFVSTCgic2thaW5ldF9rZXJuZWxzX210Lndhc20iLGltcG9ydC5tZXRhLnVybCkuaHJlZn1jYXRjaChlKXtyZXR1cm4gInNrYWluZXRfa2VybmVsc19tdC53YXNtIn19ZnVuY3Rpb24gZ2V0QmluYXJ5U3luYyhmaWxlKXtpZihmaWxlPT13YXNtQmluYXJ5RmlsZSYmd2FzbUJpbmFyeSl7cmV0dXJuIG5ldyBVaW50OEFycmF5KHdhc21CaW5hcnkpfWlmKHJlYWRCaW5hcnkpe3JldHVybiByZWFkQmluYXJ5KGZpbGUpfXRocm93ImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1hc3luYyBmdW5jdGlvbiBnZXRXYXNtQmluYXJ5KGJpbmFyeUZpbGUpe2lmKCF3YXNtQmluYXJ5KXt0cnl7dmFyIHJlc3BvbnNlPWF3YWl0IHJlYWRBc3luYyhiaW5hcnlGaWxlKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkocmVzcG9uc2UpfWNhdGNoe319cmV0dXJuIGdldEJpbmFyeVN5bmMoYmluYXJ5RmlsZSl9YXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGVBcnJheUJ1ZmZlcihiaW5hcnlGaWxlLGltcG9ydHMpe3RyeXt2YXIgYmluYXJ5PWF3YWl0IGdldFdhc21CaW5hcnkoYmluYXJ5RmlsZSk7dmFyIGluc3RhbmNlPWF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGJpbmFyeSxpbXBvcnRzKTtyZXR1cm4gaW5zdGFuY2V9Y2F0Y2gocmVhc29uKXtlcnIoYGZhaWxlZCB0byBhc3luY2hyb25vdXNseSBwcmVwYXJlIHdhc206ICR7cmVhc29ufWApO2Fib3J0KHJlYXNvbil9fWFzeW5jIGZ1bmN0aW9uIGluc3RhbnRpYXRlQXN5bmMoYmluYXJ5LGJpbmFyeUZpbGUsaW1wb3J0cyl7aWYoIWJpbmFyeSYmIUVOVklST05NRU5UX0lTX05PREUpe3RyeXt2YXIgcmVzcG9uc2U9ZmV0Y2goYmluYXJ5RmlsZSx7Y3JlZGVudGlhbHM6InNhbWUtb3JpZ2luIn0pO3ZhciBpbnN0YW50aWF0aW9uUmVzdWx0PWF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nKHJlc3BvbnNlLGltcG9ydHMpO3JldHVybiBpbnN0YW50aWF0aW9uUmVzdWx0fWNhdGNoKHJlYXNvbil7ZXJyKGB3YXNtIHN0cmVhbWluZyBjb21waWxlIGZhaWxlZDogJHtyZWFzb259YCk7ZXJyKCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvbiIpfX1yZXR1cm4gaW5zdGFudGlhdGVBcnJheUJ1ZmZlcihiaW5hcnlGaWxlLGltcG9ydHMpfWZ1bmN0aW9uIGdldFdhc21JbXBvcnRzKCl7YXNzaWduV2FzbUltcG9ydHMoKTtyZXR1cm57YTp3YXNtSW1wb3J0c319YXN5bmMgZnVuY3Rpb24gY3JlYXRlV2FzbSgpe2Z1bmN0aW9uIHJlY2VpdmVJbnN0YW5jZShpbnN0YW5jZSxtb2R1bGUpe3dhc21FeHBvcnRzPWluc3RhbmNlLmV4cG9ydHM7d2FzbUV4cG9ydHM9YXBwbHlTaWduYXR1cmVDb252ZXJzaW9ucyh3YXNtRXhwb3J0cyk7cmVnaXN0ZXJUTFNJbml0KHdhc21FeHBvcnRzWyJLIl0pO3dhc21UYWJsZT13YXNtRXhwb3J0c1sicSJdO3dhc21Nb2R1bGU9bW9kdWxlO2Fzc2lnbldhc21FeHBvcnRzKHdhc21FeHBvcnRzKTtyZXR1cm4gd2FzbUV4cG9ydHN9ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KXtyZXR1cm4gcmVjZWl2ZUluc3RhbmNlKHJlc3VsdFsiaW5zdGFuY2UiXSxyZXN1bHRbIm1vZHVsZSJdKX12YXIgaW5mbz1nZXRXYXNtSW1wb3J0cygpO2lmKE1vZHVsZVsiaW5zdGFudGlhdGVXYXNtIl0pe3JldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSxyZWplY3QpPT57TW9kdWxlWyJpbnN0YW50aWF0ZVdhc20iXShpbmZvLChtb2QsaW5zdCk9PntyZXNvbHZlKHJlY2VpdmVJbnN0YW5jZShtb2QsaW5zdCkpfSl9KX1pZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt2YXIgaW5zdGFuY2U9bmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKHdhc21Nb2R1bGUsZ2V0V2FzbUltcG9ydHMoKSk7cmV0dXJuIHJlY2VpdmVJbnN0YW5jZShpbnN0YW5jZSx3YXNtTW9kdWxlKX13YXNtQmluYXJ5RmlsZT8/PWZpbmRXYXNtQmluYXJ5KCk7dmFyIHJlc3VsdD1hd2FpdCBpbnN0YW50aWF0ZUFzeW5jKHdhc21CaW5hcnksd2FzbUJpbmFyeUZpbGUsaW5mbyk7dmFyIGV4cG9ydHM9cmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KTtyZXR1cm4gZXhwb3J0c31jbGFzcyBFeGl0U3RhdHVze25hbWU9IkV4aXRTdGF0dXMiO2NvbnN0cnVjdG9yKHN0YXR1cyl7dGhpcy5tZXNzYWdlPWBQcm9ncmFtIHRlcm1pbmF0ZWQgd2l0aCBleGl0KCR7c3RhdHVzfSlgO3RoaXMuc3RhdHVzPXN0YXR1c319dmFyIHRlcm1pbmF0ZVdvcmtlcj13b3JrZXI9Pnt3b3JrZXIudGVybWluYXRlKCk7d29ya2VyLm9ubWVzc2FnZT1lPT57fX07dmFyIGNsZWFudXBUaHJlYWQ9cHRocmVhZF9wdHI9Pnt2YXIgd29ya2VyPVBUaHJlYWQucHRocmVhZHNbcHRocmVhZF9wdHJdO1BUaHJlYWQucmV0dXJuV29ya2VyVG9Qb29sKHdvcmtlcil9O3ZhciBjYWxsUnVudGltZUNhbGxiYWNrcz1jYWxsYmFja3M9Pnt3aGlsZShjYWxsYmFja3MubGVuZ3RoPjApe2NhbGxiYWNrcy5zaGlmdCgpKE1vZHVsZSl9fTt2YXIgb25QcmVSdW5zPVtdO3ZhciBhZGRPblByZVJ1bj1jYj0+b25QcmVSdW5zLnB1c2goY2IpO3ZhciBydW5EZXBlbmRlbmNpZXM9MDt2YXIgZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7dmFyIHJlbW92ZVJ1bkRlcGVuZGVuY3k9aWQ9PntydW5EZXBlbmRlbmNpZXMtLTtNb2R1bGVbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXT8uKHJ1bkRlcGVuZGVuY2llcyk7aWYocnVuRGVwZW5kZW5jaWVzPT0wKXtpZihkZXBlbmRlbmNpZXNGdWxmaWxsZWQpe3ZhciBjYWxsYmFjaz1kZXBlbmRlbmNpZXNGdWxmaWxsZWQ7ZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7Y2FsbGJhY2soKX19fTt2YXIgYWRkUnVuRGVwZW5kZW5jeT1pZD0+e3J1bkRlcGVuZGVuY2llcysrO01vZHVsZVsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdPy4ocnVuRGVwZW5kZW5jaWVzKX07dmFyIHNwYXduVGhyZWFkPXRocmVhZFBhcmFtcz0+e3ZhciB3b3JrZXI9UFRocmVhZC5nZXROZXdXb3JrZXIoKTtpZighd29ya2VyKXtyZXR1cm4gNn1QVGhyZWFkLnJ1bm5pbmdXb3JrZXJzLnB1c2god29ya2VyKTtQVGhyZWFkLnB0aHJlYWRzW3RocmVhZFBhcmFtcy5wdGhyZWFkX3B0cl09d29ya2VyO3dvcmtlci5wdGhyZWFkX3B0cj10aHJlYWRQYXJhbXMucHRocmVhZF9wdHI7dmFyIG1zZz17Y21kOiJydW4iLHN0YXJ0X3JvdXRpbmU6dGhyZWFkUGFyYW1zLnN0YXJ0Um91dGluZSxhcmc6dGhyZWFkUGFyYW1zLmFyZyxwdGhyZWFkX3B0cjp0aHJlYWRQYXJhbXMucHRocmVhZF9wdHJ9O2lmKEVOVklST05NRU5UX0lTX05PREUpe3dvcmtlci51bnJlZigpfXdvcmtlci5wb3N0TWVzc2FnZShtc2csdGhyZWFkUGFyYW1zLnRyYW5zZmVyTGlzdCk7cmV0dXJuIDB9O3ZhciBydW50aW1lS2VlcGFsaXZlQ291bnRlcj0wO3ZhciBrZWVwUnVudGltZUFsaXZlPSgpPT5ub0V4aXRSdW50aW1lfHxydW50aW1lS2VlcGFsaXZlQ291bnRlcj4wO3ZhciBzdGFja1NhdmU9KCk9Pl9lbXNjcmlwdGVuX3N0YWNrX2dldF9jdXJyZW50KCk7dmFyIHN0YWNrUmVzdG9yZT12YWw9Pl9fZW1zY3JpcHRlbl9zdGFja19yZXN0b3JlKHZhbCk7dmFyIHN0YWNrQWxsb2M9c3o9Pl9fZW1zY3JpcHRlbl9zdGFja19hbGxvYyhzeik7dmFyIHByb3h5VG9NYWluVGhyZWFkPShmdW5jSW5kZXgsZW1Bc21BZGRyLHN5bmMsLi4uY2FsbEFyZ3MpPT57dmFyIHNlcmlhbGl6ZWROdW1DYWxsQXJncz1jYWxsQXJncy5sZW5ndGgqMjt2YXIgc3A9c3RhY2tTYXZlKCk7dmFyIGFyZ3M9c3RhY2tBbGxvYyhzZXJpYWxpemVkTnVtQ2FsbEFyZ3MqOCk7dmFyIGI9YXJncz4+PjM7Zm9yKHZhciBpPTA7aTxjYWxsQXJncy5sZW5ndGg7aSsrKXt2YXIgYXJnPWNhbGxBcmdzW2ldO2lmKHR5cGVvZiBhcmc9PSJiaWdpbnQiKXsoZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaT4+PjBdPTFuOyhncm93TWVtVmlld3MoKSxIRUFQNjQpW2IrMippKzE+Pj4wXT1hcmd9ZWxzZXsoZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaT4+PjBdPTBuOyhncm93TWVtVmlld3MoKSxIRUFQRjY0KVtiKzIqaSsxPj4+MF09YXJnfX12YXIgcnRuPV9fZW1zY3JpcHRlbl9ydW5fanNfb25fbWFpbl90aHJlYWQoZnVuY0luZGV4LGVtQXNtQWRkcixzZXJpYWxpemVkTnVtQ2FsbEFyZ3MsYXJncyxzeW5jKTtzdGFja1Jlc3RvcmUoc3ApO3JldHVybiBydG59O2Z1bmN0aW9uIF9wcm9jX2V4aXQoY29kZSl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRClyZXR1cm4gcHJveHlUb01haW5UaHJlYWQoMCwwLDEsY29kZSk7RVhJVFNUQVRVUz1jb2RlO2lmKCFrZWVwUnVudGltZUFsaXZlKCkpe1BUaHJlYWQudGVybWluYXRlQWxsVGhyZWFkcygpO01vZHVsZVsib25FeGl0Il0/Lihjb2RlKTtBQk9SVD10cnVlfXF1aXRfKGNvZGUsbmV3IEV4aXRTdGF0dXMoY29kZSkpfWZ1bmN0aW9uIGV4aXRPbk1haW5UaHJlYWQocmV0dXJuQ29kZSl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRClyZXR1cm4gcHJveHlUb01haW5UaHJlYWQoMSwwLDAscmV0dXJuQ29kZSk7X2V4aXQocmV0dXJuQ29kZSl9dmFyIGV4aXRKUz0oc3RhdHVzLGltcGxpY2l0KT0+e0VYSVRTVEFUVVM9c3RhdHVzO2lmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpe2V4aXRPbk1haW5UaHJlYWQoc3RhdHVzKTt0aHJvdyJ1bndpbmQifV9wcm9jX2V4aXQoc3RhdHVzKX07dmFyIF9leGl0PWV4aXRKUzt2YXIgUFRocmVhZD17dW51c2VkV29ya2VyczpbXSxydW5uaW5nV29ya2VyczpbXSx0bHNJbml0RnVuY3Rpb25zOltdLHB0aHJlYWRzOnt9LGluaXQoKXtpZighRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7UFRocmVhZC5pbml0TWFpblRocmVhZCgpfX0saW5pdE1haW5UaHJlYWQoKXt2YXIgcHRocmVhZFBvb2xTaXplPTQ7d2hpbGUocHRocmVhZFBvb2xTaXplLS0pe1BUaHJlYWQuYWxsb2NhdGVVbnVzZWRXb3JrZXIoKX1hZGRPblByZVJ1bihhc3luYygpPT57dmFyIHB0aHJlYWRQb29sUmVhZHk9UFRocmVhZC5sb2FkV2FzbU1vZHVsZVRvQWxsV29ya2VycygpO2FkZFJ1bkRlcGVuZGVuY3koImxvYWRpbmctd29ya2VycyIpO2F3YWl0IHB0aHJlYWRQb29sUmVhZHk7cmVtb3ZlUnVuRGVwZW5kZW5jeSgibG9hZGluZy13b3JrZXJzIil9KX0sdGVybWluYXRlQWxsVGhyZWFkczooKT0+e2Zvcih2YXIgd29ya2VyIG9mIFBUaHJlYWQucnVubmluZ1dvcmtlcnMpe3Rlcm1pbmF0ZVdvcmtlcih3b3JrZXIpfWZvcih2YXIgd29ya2VyIG9mIFBUaHJlYWQudW51c2VkV29ya2Vycyl7dGVybWluYXRlV29ya2VyKHdvcmtlcil9UFRocmVhZC51bnVzZWRXb3JrZXJzPVtdO1BUaHJlYWQucnVubmluZ1dvcmtlcnM9W107UFRocmVhZC5wdGhyZWFkcz17fX0scmV0dXJuV29ya2VyVG9Qb29sOndvcmtlcj0+e3ZhciBwdGhyZWFkX3B0cj13b3JrZXIucHRocmVhZF9wdHI7ZGVsZXRlIFBUaHJlYWQucHRocmVhZHNbcHRocmVhZF9wdHJdO1BUaHJlYWQudW51c2VkV29ya2Vycy5wdXNoKHdvcmtlcik7UFRocmVhZC5ydW5uaW5nV29ya2Vycy5zcGxpY2UoUFRocmVhZC5ydW5uaW5nV29ya2Vycy5pbmRleE9mKHdvcmtlciksMSk7d29ya2VyLnB0aHJlYWRfcHRyPTA7X19lbXNjcmlwdGVuX3RocmVhZF9mcmVlX2RhdGEocHRocmVhZF9wdHIpfSx0aHJlYWRJbml0VExTKCl7UFRocmVhZC50bHNJbml0RnVuY3Rpb25zLmZvckVhY2goZj0+ZigpKX0sbG9hZFdhc21Nb2R1bGVUb1dvcmtlcjp3b3JrZXI9Pm5ldyBQcm9taXNlKG9uRmluaXNoZWRMb2FkaW5nPT57d29ya2VyLm9ubWVzc2FnZT1lPT57dmFyIGQ9ZVsiZGF0YSJdO3ZhciBjbWQ9ZC5jbWQ7aWYoZC50YXJnZXRUaHJlYWQmJmQudGFyZ2V0VGhyZWFkIT1fcHRocmVhZF9zZWxmKCkpe3ZhciB0YXJnZXRXb3JrZXI9UFRocmVhZC5wdGhyZWFkc1tkLnRhcmdldFRocmVhZF07aWYodGFyZ2V0V29ya2VyKXt0YXJnZXRXb3JrZXIucG9zdE1lc3NhZ2UoZCxkLnRyYW5zZmVyTGlzdCl9ZWxzZXtlcnIoYEludGVybmFsIGVycm9yISBXb3JrZXIgc2VudCBhIG1lc3NhZ2UgIiR7Y21kfSIgdG8gdGFyZ2V0IHB0aHJlYWQgJHtkLnRhcmdldFRocmVhZH0sIGJ1dCB0aGF0IHRocmVhZCBubyBsb25nZXIgZXhpc3RzIWApfXJldHVybn1pZihjbWQ9PT0iY2hlY2tNYWlsYm94Iil7Y2hlY2tNYWlsYm94KCl9ZWxzZSBpZihjbWQ9PT0ic3Bhd25UaHJlYWQiKXtzcGF3blRocmVhZChkKX1lbHNlIGlmKGNtZD09PSJjbGVhbnVwVGhyZWFkIil7Y2FsbFVzZXJDYWxsYmFjaygoKT0+Y2xlYW51cFRocmVhZChkLnRocmVhZCkpfWVsc2UgaWYoY21kPT09ImxvYWRlZCIpe3dvcmtlci5sb2FkZWQ9dHJ1ZTtpZihFTlZJUk9OTUVOVF9JU19OT0RFJiYhd29ya2VyLnB0aHJlYWRfcHRyKXt3b3JrZXIudW5yZWYoKX1vbkZpbmlzaGVkTG9hZGluZyh3b3JrZXIpfWVsc2UgaWYoZC50YXJnZXQ9PT0ic2V0aW1tZWRpYXRlIil7d29ya2VyLnBvc3RNZXNzYWdlKGQpfWVsc2UgaWYoY21kPT09InVuY2F1Z2h0RXhjZXB0aW9uIil7d29ya2VyLm9uZXJyb3IoZC5lcnJvcil9ZWxzZSBpZihjbWQ9PT0iY2FsbEhhbmRsZXIiKXtNb2R1bGVbZC5oYW5kbGVyXSguLi5kLmFyZ3MpfWVsc2UgaWYoY21kKXtlcnIoYHdvcmtlciBzZW50IGFuIHVua25vd24gY29tbWFuZCAke2NtZH1gKX19O3dvcmtlci5vbmVycm9yPWU9Pnt2YXIgbWVzc2FnZT0id29ya2VyIHNlbnQgYW4gZXJyb3IhIjtlcnIoYCR7bWVzc2FnZX0gJHtlLmZpbGVuYW1lfToke2UubGluZW5vfTogJHtlLm1lc3NhZ2V9YCk7dGhyb3cgZX07aWYoRU5WSVJPTk1FTlRfSVNfTk9ERSl7d29ya2VyLm9uKCJtZXNzYWdlIixkYXRhPT53b3JrZXIub25tZXNzYWdlKHtkYXRhfSkpO3dvcmtlci5vbigiZXJyb3IiLGU9Pndvcmtlci5vbmVycm9yKGUpKX12YXIgaGFuZGxlcnM9W107dmFyIGtub3duSGFuZGxlcnM9WyJvbkV4aXQiLCJvbkFib3J0IiwicHJpbnQiLCJwcmludEVyciJdO2Zvcih2YXIgaGFuZGxlciBvZiBrbm93bkhhbmRsZXJzKXtpZihNb2R1bGUucHJvcGVydHlJc0VudW1lcmFibGUoaGFuZGxlcikpe2hhbmRsZXJzLnB1c2goaGFuZGxlcil9fXdvcmtlci5wb3N0TWVzc2FnZSh7Y21kOiJsb2FkIixoYW5kbGVycyx3YXNtTWVtb3J5LHdhc21Nb2R1bGV9KX0pLGFzeW5jIGxvYWRXYXNtTW9kdWxlVG9BbGxXb3JrZXJzKCl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7cmV0dXJufWxldCBwdGhyZWFkUG9vbFJlYWR5PVByb21pc2UuYWxsKFBUaHJlYWQudW51c2VkV29ya2Vycy5tYXAoUFRocmVhZC5sb2FkV2FzbU1vZHVsZVRvV29ya2VyKSk7cmV0dXJuIHB0aHJlYWRQb29sUmVhZHl9LGFsbG9jYXRlVW51c2VkV29ya2VyKCl7dmFyIHdvcmtlcjtpZihNb2R1bGVbIm1haW5TY3JpcHRVcmxPckJsb2IiXSl7dmFyIHB0aHJlYWRNYWluSnM9TW9kdWxlWyJtYWluU2NyaXB0VXJsT3JCbG9iIl07aWYodHlwZW9mIHB0aHJlYWRNYWluSnMhPSJzdHJpbmciKXtwdGhyZWFkTWFpbkpzPVVSTC5jcmVhdGVPYmplY3RVUkwocHRocmVhZE1haW5Kcyl9d29ya2VyPW5ldyBXb3JrZXIoRU5WSVJPTk1FTlRfSVNfTk9ERSYmdHlwZW9mIHB0aHJlYWRNYWluSnM9PSJzdHJpbmciJiZwdGhyZWFkTWFpbkpzLnN0YXJ0c1dpdGgoImRhdGE6Iik/bmV3IFVSTChwdGhyZWFkTWFpbkpzKTpwdGhyZWFkTWFpbkpzLHt0eXBlOiJtb2R1bGUiLHdvcmtlckRhdGE6ImVtLXB0aHJlYWQiLG5hbWU6ImVtLXB0aHJlYWQifSl9ZWxzZSB3b3JrZXI9bmV3IFdvcmtlcihuZXcgVVJMKCJza2FpbmV0X2tlcm5lbHNfbXQubWpzIixpbXBvcnQubWV0YS51cmwpLHt0eXBlOiJtb2R1bGUiLHdvcmtlckRhdGE6ImVtLXB0aHJlYWQiLG5hbWU6ImVtLXB0aHJlYWQifSk7UFRocmVhZC51bnVzZWRXb3JrZXJzLnB1c2god29ya2VyKX0sZ2V0TmV3V29ya2VyKCl7aWYoUFRocmVhZC51bnVzZWRXb3JrZXJzLmxlbmd0aD09MCl7UFRocmVhZC5hbGxvY2F0ZVVudXNlZFdvcmtlcigpO1BUaHJlYWQubG9hZFdhc21Nb2R1bGVUb1dvcmtlcihQVGhyZWFkLnVudXNlZFdvcmtlcnNbMF0pfXJldHVybiBQVGhyZWFkLnVudXNlZFdvcmtlcnMucG9wKCl9fTt2YXIgb25Qb3N0UnVucz1bXTt2YXIgYWRkT25Qb3N0UnVuPWNiPT5vblBvc3RSdW5zLnB1c2goY2IpO2Z1bmN0aW9uIGVzdGFibGlzaFN0YWNrU3BhY2UocHRocmVhZF9wdHIpe3ZhciBzdGFja0hpZ2g9KGdyb3dNZW1WaWV3cygpLEhFQVBVMzIpW3B0aHJlYWRfcHRyKzUyPj4+Mj4+PjBdO3ZhciBzdGFja1NpemU9KGdyb3dNZW1WaWV3cygpLEhFQVBVMzIpW3B0aHJlYWRfcHRyKzU2Pj4+Mj4+PjBdO3ZhciBzdGFja0xvdz1zdGFja0hpZ2gtc3RhY2tTaXplO19lbXNjcmlwdGVuX3N0YWNrX3NldF9saW1pdHMoc3RhY2tIaWdoLHN0YWNrTG93KTtzdGFja1Jlc3RvcmUoc3RhY2tIaWdoKX12YXIgd2FzbVRhYmxlTWlycm9yPVtdO3ZhciB3YXNtVGFibGU7dmFyIGdldFdhc21UYWJsZUVudHJ5PWZ1bmNQdHI9Pnt2YXIgZnVuYz13YXNtVGFibGVNaXJyb3JbZnVuY1B0cl07aWYoIWZ1bmMpe3dhc21UYWJsZU1pcnJvcltmdW5jUHRyXT1mdW5jPXdhc21UYWJsZS5nZXQoZnVuY1B0cil9cmV0dXJuIGZ1bmN9O3ZhciBpbnZva2VFbnRyeVBvaW50PShwdHIsYXJnKT0+e3J1bnRpbWVLZWVwYWxpdmVDb3VudGVyPTA7bm9FeGl0UnVudGltZT0wO3ZhciByZXN1bHQ9Z2V0V2FzbVRhYmxlRW50cnkocHRyKShhcmcpO2Z1bmN0aW9uIGZpbmlzaChyZXN1bHQpe2lmKGtlZXBSdW50aW1lQWxpdmUoKSl7RVhJVFNUQVRVUz1yZXN1bHQ7cmV0dXJufV9fZW1zY3JpcHRlbl90aHJlYWRfZXhpdChyZXN1bHQpfWZpbmlzaChyZXN1bHQpfTt2YXIgbm9FeGl0UnVudGltZT10cnVlO3ZhciByZWdpc3RlclRMU0luaXQ9dGxzSW5pdEZ1bmM9PlBUaHJlYWQudGxzSW5pdEZ1bmN0aW9ucy5wdXNoKHRsc0luaXRGdW5jKTtmdW5jdGlvbiBwdGhyZWFkQ3JlYXRlUHJveGllZChwdGhyZWFkX3B0cixhdHRyLHN0YXJ0Um91dGluZSxhcmcpe2lmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpcmV0dXJuIHByb3h5VG9NYWluVGhyZWFkKDIsMCwxLHB0aHJlYWRfcHRyLGF0dHIsc3RhcnRSb3V0aW5lLGFyZyk7cmV0dXJuIF9fX3B0aHJlYWRfY3JlYXRlX2pzKHB0aHJlYWRfcHRyLGF0dHIsc3RhcnRSb3V0aW5lLGFyZyl9dmFyIF9lbXNjcmlwdGVuX2hhc190aHJlYWRpbmdfc3VwcG9ydD0oKT0+dHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyIT0idW5kZWZpbmVkIjtmdW5jdGlvbiBfX19wdGhyZWFkX2NyZWF0ZV9qcyhwdGhyZWFkX3B0cixhdHRyLHN0YXJ0Um91dGluZSxhcmcpe3B0aHJlYWRfcHRyPj4+PTA7YXR0cj4+Pj0wO3N0YXJ0Um91dGluZT4+Pj0wO2FyZz4+Pj0wO2lmKCFfZW1zY3JpcHRlbl9oYXNfdGhyZWFkaW5nX3N1cHBvcnQoKSl7cmV0dXJuIDZ9dmFyIHRyYW5zZmVyTGlzdD1bXTt2YXIgZXJyb3I9MDtpZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEJiYodHJhbnNmZXJMaXN0Lmxlbmd0aD09PTB8fGVycm9yKSl7cmV0dXJuIHB0aHJlYWRDcmVhdGVQcm94aWVkKHB0aHJlYWRfcHRyLGF0dHIsc3RhcnRSb3V0aW5lLGFyZyl9aWYoZXJyb3IpcmV0dXJuIGVycm9yO3ZhciB0aHJlYWRQYXJhbXM9e3N0YXJ0Um91dGluZSxwdGhyZWFkX3B0cixhcmcsdHJhbnNmZXJMaXN0fTtpZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt0aHJlYWRQYXJhbXMuY21kPSJzcGF3blRocmVhZCI7cG9zdE1lc3NhZ2UodGhyZWFkUGFyYW1zLHRyYW5zZmVyTGlzdCk7cmV0dXJuIDB9cmV0dXJuIHNwYXduVGhyZWFkKHRocmVhZFBhcmFtcyl9ZnVuY3Rpb24gX19lbXNjcmlwdGVuX2luaXRfbWFpbl90aHJlYWRfanModGIpe3RiPj4+PTA7X19lbXNjcmlwdGVuX3RocmVhZF9pbml0KHRiLCFFTlZJUk9OTUVOVF9JU19XT1JLRVIsMSwhRU5WSVJPTk1FTlRfSVNfV0VCLDY1NTM2LGZhbHNlKTtQVGhyZWFkLnRocmVhZEluaXRUTFMoKX12YXIgaGFuZGxlRXhjZXB0aW9uPWU9PntpZihlIGluc3RhbmNlb2YgRXhpdFN0YXR1c3x8ZT09InVud2luZCIpe3JldHVybiBFWElUU1RBVFVTfXF1aXRfKDEsZSl9O3ZhciBtYXliZUV4aXQ9KCk9PntpZigha2VlcFJ1bnRpbWVBbGl2ZSgpKXt0cnl7aWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7aWYoX3B0aHJlYWRfc2VsZigpKV9fZW1zY3JpcHRlbl90aHJlYWRfZXhpdChFWElUU1RBVFVTKTtyZXR1cm59X2V4aXQoRVhJVFNUQVRVUyl9Y2F0Y2goZSl7aGFuZGxlRXhjZXB0aW9uKGUpfX19O3ZhciBjYWxsVXNlckNhbGxiYWNrPWZ1bmM9PntpZihBQk9SVCl7cmV0dXJufXRyeXtmdW5jKCk7bWF5YmVFeGl0KCl9Y2F0Y2goZSl7aGFuZGxlRXhjZXB0aW9uKGUpfX07ZnVuY3Rpb24gX19lbXNjcmlwdGVuX3RocmVhZF9tYWlsYm94X2F3YWl0KHB0aHJlYWRfcHRyKXtwdGhyZWFkX3B0cj4+Pj0wO2lmKHR5cGVvZiBBdG9taWNzLndhaXRBc3luYz09PSJmdW5jdGlvbiIpe3ZhciB3YWl0PUF0b21pY3Mud2FpdEFzeW5jKChncm93TWVtVmlld3MoKSxIRUFQMzIpLHB0aHJlYWRfcHRyPj4+MixwdGhyZWFkX3B0cik7d2FpdC52YWx1ZS50aGVuKGNoZWNrTWFpbGJveCk7dmFyIHdhaXRpbmdBc3luYz1wdGhyZWFkX3B0cisxMjg7QXRvbWljcy5zdG9yZSgoZ3Jvd01lbVZpZXdzKCksSEVBUDMyKSx3YWl0aW5nQXN5bmM+Pj4yLDEpfX12YXIgY2hlY2tNYWlsYm94PSgpPT5jYWxsVXNlckNhbGxiYWNrKCgpPT57dmFyIHB0aHJlYWRfcHRyPV9wdGhyZWFkX3NlbGYoKTtpZihwdGhyZWFkX3B0cil7X19lbXNjcmlwdGVuX3RocmVhZF9tYWlsYm94X2F3YWl0KHB0aHJlYWRfcHRyKTtfX2Vtc2NyaXB0ZW5fY2hlY2tfbWFpbGJveCgpfX0pO2Z1bmN0aW9uIF9fZW1zY3JpcHRlbl9ub3RpZnlfbWFpbGJveF9wb3N0bWVzc2FnZSh0YXJnZXRUaHJlYWQsY3VyclRocmVhZElkKXt0YXJnZXRUaHJlYWQ+Pj49MDtjdXJyVGhyZWFkSWQ+Pj49MDtpZih0YXJnZXRUaHJlYWQ9PWN1cnJUaHJlYWRJZCl7c2V0VGltZW91dChjaGVja01haWxib3gpfWVsc2UgaWYoRU5WSVJPTk1FTlRfSVNfUFRIUkVBRCl7cG9zdE1lc3NhZ2Uoe3RhcmdldFRocmVhZCxjbWQ6ImNoZWNrTWFpbGJveCJ9KX1lbHNle3ZhciB3b3JrZXI9UFRocmVhZC5wdGhyZWFkc1t0YXJnZXRUaHJlYWRdO2lmKCF3b3JrZXIpe3JldHVybn13b3JrZXIucG9zdE1lc3NhZ2Uoe2NtZDoiY2hlY2tNYWlsYm94In0pfX12YXIgcHJveGllZEpTQ2FsbEFyZ3M9W107ZnVuY3Rpb24gX19lbXNjcmlwdGVuX3JlY2VpdmVfb25fbWFpbl90aHJlYWRfanMoZnVuY0luZGV4LGVtQXNtQWRkcixjYWxsaW5nVGhyZWFkLG51bUNhbGxBcmdzLGFyZ3Mpe2VtQXNtQWRkcj4+Pj0wO2NhbGxpbmdUaHJlYWQ+Pj49MDthcmdzPj4+PTA7bnVtQ2FsbEFyZ3MvPTI7cHJveGllZEpTQ2FsbEFyZ3MubGVuZ3RoPW51bUNhbGxBcmdzO3ZhciBiPWFyZ3M+Pj4zO2Zvcih2YXIgaT0wO2k8bnVtQ2FsbEFyZ3M7aSsrKXtpZigoZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaT4+PjBdKXtwcm94aWVkSlNDYWxsQXJnc1tpXT0oZ3Jvd01lbVZpZXdzKCksSEVBUDY0KVtiKzIqaSsxPj4+MF19ZWxzZXtwcm94aWVkSlNDYWxsQXJnc1tpXT0oZ3Jvd01lbVZpZXdzKCksSEVBUEY2NClbYisyKmkrMT4+PjBdfX12YXIgZnVuYz1wcm94aWVkRnVuY3Rpb25UYWJsZVtmdW5jSW5kZXhdO1BUaHJlYWQuY3VycmVudFByb3hpZWRPcGVyYXRpb25DYWxsZXJUaHJlYWQ9Y2FsbGluZ1RocmVhZDt2YXIgcnRuPWZ1bmMoLi4ucHJveGllZEpTQ2FsbEFyZ3MpO1BUaHJlYWQuY3VycmVudFByb3hpZWRPcGVyYXRpb25DYWxsZXJUaHJlYWQ9MDtyZXR1cm4gcnRufWZ1bmN0aW9uIF9fZW1zY3JpcHRlbl90aHJlYWRfY2xlYW51cCh0aHJlYWQpe3RocmVhZD4+Pj0wO2lmKCFFTlZJUk9OTUVOVF9JU19QVEhSRUFEKWNsZWFudXBUaHJlYWQodGhyZWFkKTtlbHNlIHBvc3RNZXNzYWdlKHtjbWQ6ImNsZWFudXBUaHJlYWQiLHRocmVhZH0pfWZ1bmN0aW9uIF9fZW1zY3JpcHRlbl90aHJlYWRfc2V0X3N0cm9uZ3JlZih0aHJlYWQpe3RocmVhZD4+Pj0wO2lmKEVOVklST05NRU5UX0lTX05PREUpe1BUaHJlYWQucHRocmVhZHNbdGhyZWFkXS5yZWYoKX19dmFyIF9lbXNjcmlwdGVuX2dldF9ub3c9KCk9PnBlcmZvcm1hbmNlLnRpbWVPcmlnaW4rcGVyZm9ybWFuY2Uubm93KCk7dmFyIF9lbXNjcmlwdGVuX2NoZWNrX2Jsb2NraW5nX2FsbG93ZWQ9KCk9Pnt9O3ZhciBydW50aW1lS2VlcGFsaXZlUHVzaD0oKT0+e3J1bnRpbWVLZWVwYWxpdmVDb3VudGVyKz0xfTt2YXIgX2Vtc2NyaXB0ZW5fZXhpdF93aXRoX2xpdmVfcnVudGltZT0oKT0+e3J1bnRpbWVLZWVwYWxpdmVQdXNoKCk7dGhyb3cidW53aW5kIn07dmFyIGdldEhlYXBNYXg9KCk9PjQyOTQ5MDE3NjA7dmFyIGFsaWduTWVtb3J5PShzaXplLGFsaWdubWVudCk9Pk1hdGguY2VpbChzaXplL2FsaWdubWVudCkqYWxpZ25tZW50O3ZhciBncm93TWVtb3J5PXNpemU9Pnt2YXIgb2xkSGVhcFNpemU9d2FzbU1lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aDt2YXIgcGFnZXM9KHNpemUtb2xkSGVhcFNpemUrNjU1MzUpLzY1NTM2fDA7dHJ5e3dhc21NZW1vcnkuZ3JvdyhwYWdlcyk7dXBkYXRlTWVtb3J5Vmlld3MoKTtyZXR1cm4gMX1jYXRjaChlKXt9fTtmdW5jdGlvbiBfZW1zY3JpcHRlbl9yZXNpemVfaGVhcChyZXF1ZXN0ZWRTaXplKXtyZXF1ZXN0ZWRTaXplPj4+PTA7dmFyIG9sZFNpemU9KGdyb3dNZW1WaWV3cygpLEhFQVBVOCkubGVuZ3RoO2lmKHJlcXVlc3RlZFNpemU8PW9sZFNpemUpe3JldHVybiBmYWxzZX12YXIgbWF4SGVhcFNpemU9Z2V0SGVhcE1heCgpO2lmKHJlcXVlc3RlZFNpemU+bWF4SGVhcFNpemUpe3JldHVybiBmYWxzZX1mb3IodmFyIGN1dERvd249MTtjdXREb3duPD00O2N1dERvd24qPTIpe3ZhciBvdmVyR3Jvd25IZWFwU2l6ZT1vbGRTaXplKigxKy4yL2N1dERvd24pO292ZXJHcm93bkhlYXBTaXplPU1hdGgubWluKG92ZXJHcm93bkhlYXBTaXplLHJlcXVlc3RlZFNpemUrMTAwNjYzMjk2KTt2YXIgbmV3U2l6ZT1NYXRoLm1pbihtYXhIZWFwU2l6ZSxhbGlnbk1lbW9yeShNYXRoLm1heChyZXF1ZXN0ZWRTaXplLG92ZXJHcm93bkhlYXBTaXplKSw2NTUzNikpO3ZhciByZXBsYWNlbWVudD1ncm93TWVtb3J5KG5ld1NpemUpO2lmKHJlcGxhY2VtZW50KXtyZXR1cm4gdHJ1ZX19cmV0dXJuIGZhbHNlfXZhciBwcmludENoYXJCdWZmZXJzPVtudWxsLFtdLFtdXTt2YXIgVVRGOERlY29kZXI9dHlwZW9mIFRleHREZWNvZGVyIT0idW5kZWZpbmVkIj9uZXcgVGV4dERlY29kZXI6dW5kZWZpbmVkO3ZhciBmaW5kU3RyaW5nRW5kPShoZWFwT3JBcnJheSxpZHgsbWF4Qnl0ZXNUb1JlYWQsaWdub3JlTnVsKT0+e3ZhciBtYXhJZHg9aWR4K21heEJ5dGVzVG9SZWFkO2lmKGlnbm9yZU51bClyZXR1cm4gbWF4SWR4O3doaWxlKGhlYXBPckFycmF5W2lkeF0mJiEoaWR4Pj1tYXhJZHgpKSsraWR4O3JldHVybiBpZHh9O3ZhciBVVEY4QXJyYXlUb1N0cmluZz0oaGVhcE9yQXJyYXksaWR4PTAsbWF4Qnl0ZXNUb1JlYWQsaWdub3JlTnVsKT0+e2lkeD4+Pj0wO3ZhciBlbmRQdHI9ZmluZFN0cmluZ0VuZChoZWFwT3JBcnJheSxpZHgsbWF4Qnl0ZXNUb1JlYWQsaWdub3JlTnVsKTtpZihlbmRQdHItaWR4PjE2JiZoZWFwT3JBcnJheS5idWZmZXImJlVURjhEZWNvZGVyKXtyZXR1cm4gVVRGOERlY29kZXIuZGVjb2RlKGhlYXBPckFycmF5LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyP2hlYXBPckFycmF5LnN1YmFycmF5KGlkeCxlbmRQdHIpOmhlYXBPckFycmF5LnNsaWNlKGlkeCxlbmRQdHIpKX12YXIgc3RyPSIiO3doaWxlKGlkeDxlbmRQdHIpe3ZhciB1MD1oZWFwT3JBcnJheVtpZHgrK107aWYoISh1MCYxMjgpKXtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUodTApO2NvbnRpbnVlfXZhciB1MT1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjIyNCk9PTE5Mil7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKCh1MCYzMSk8PDZ8dTEpO2NvbnRpbnVlfXZhciB1Mj1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjI0MCk9PTIyNCl7dTA9KHUwJjE1KTw8MTJ8dTE8PDZ8dTJ9ZWxzZXt1MD0odTAmNyk8PDE4fHUxPDwxMnx1Mjw8NnxoZWFwT3JBcnJheVtpZHgrK10mNjN9aWYodTA8NjU1MzYpe3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSh1MCl9ZWxzZXt2YXIgY2g9dTAtNjU1MzY7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGNoPj4xMCw1NjMyMHxjaCYxMDIzKX19cmV0dXJuIHN0cn07dmFyIHByaW50Q2hhcj0oc3RyZWFtLGN1cnIpPT57dmFyIGJ1ZmZlcj1wcmludENoYXJCdWZmZXJzW3N0cmVhbV07aWYoY3Vycj09PTB8fGN1cnI9PT0xMCl7KHN0cmVhbT09PTE/b3V0OmVycikoVVRGOEFycmF5VG9TdHJpbmcoYnVmZmVyKSk7YnVmZmVyLmxlbmd0aD0wfWVsc2V7YnVmZmVyLnB1c2goY3Vycil9fTtmdW5jdGlvbiBfZmRfd3JpdGUoZmQsaW92LGlvdmNudCxwbnVtKXtpZihFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXJldHVybiBwcm94eVRvTWFpblRocmVhZCgzLDAsMSxmZCxpb3YsaW92Y250LHBudW0pO2lvdj4+Pj0wO2lvdmNudD4+Pj0wO3BudW0+Pj49MDt2YXIgbnVtPTA7Zm9yKHZhciBpPTA7aTxpb3ZjbnQ7aSsrKXt2YXIgcHRyPShncm93TWVtVmlld3MoKSxIRUFQVTMyKVtpb3Y+Pj4yPj4+MF07dmFyIGxlbj0oZ3Jvd01lbVZpZXdzKCksSEVBUFUzMilbaW92KzQ+Pj4yPj4+MF07aW92Kz04O2Zvcih2YXIgaj0wO2o8bGVuO2orKyl7cHJpbnRDaGFyKGZkLChncm93TWVtVmlld3MoKSxIRUFQVTgpW3B0citqPj4+MF0pfW51bSs9bGVufShncm93TWVtVmlld3MoKSxIRUFQVTMyKVtwbnVtPj4+Mj4+PjBdPW51bTtyZXR1cm4gMH1QVGhyZWFkLmluaXQoKTt7aW5pdE1lbW9yeSgpO2lmKE1vZHVsZVsibm9FeGl0UnVudGltZSJdKW5vRXhpdFJ1bnRpbWU9TW9kdWxlWyJub0V4aXRSdW50aW1lIl07aWYoTW9kdWxlWyJwcmludCJdKW91dD1Nb2R1bGVbInByaW50Il07aWYoTW9kdWxlWyJwcmludEVyciJdKWVycj1Nb2R1bGVbInByaW50RXJyIl07aWYoTW9kdWxlWyJ3YXNtQmluYXJ5Il0pd2FzbUJpbmFyeT1Nb2R1bGVbIndhc21CaW5hcnkiXTtpZihNb2R1bGVbImFyZ3VtZW50cyJdKWFyZ3VtZW50c189TW9kdWxlWyJhcmd1bWVudHMiXTtpZihNb2R1bGVbInRoaXNQcm9ncmFtIl0pdGhpc1Byb2dyYW09TW9kdWxlWyJ0aGlzUHJvZ3JhbSJdO2lmKE1vZHVsZVsicHJlSW5pdCJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVJbml0Il09PSJmdW5jdGlvbiIpTW9kdWxlWyJwcmVJbml0Il09W01vZHVsZVsicHJlSW5pdCJdXTt3aGlsZShNb2R1bGVbInByZUluaXQiXS5sZW5ndGg+MCl7TW9kdWxlWyJwcmVJbml0Il0uc2hpZnQoKSgpfX19TW9kdWxlWyJ3YXNtTWVtb3J5Il09d2FzbU1lbW9yeTt2YXIgcHJveGllZEZ1bmN0aW9uVGFibGU9W19wcm9jX2V4aXQsZXhpdE9uTWFpblRocmVhZCxwdGhyZWFkQ3JlYXRlUHJveGllZCxfZmRfd3JpdGVdO3ZhciBfc2thaW5ldF9mcDMyX21hdG11bCxfc2thaW5ldF9mcDMyX21hdG11bF93dCxfc2thaW5ldF9iZjE2X21hdG11bCxfc2thaW5ldF9mcDE2X21hdG11bCxfc2thaW5ldF9xNF8wX21hdG11bCxfc2thaW5ldF9xNF8wX21hdG11bF9ybSxfc2thaW5ldF9xNV8wX21hdG11bCxfbWFsbG9jLF9mcmVlLF9za2FpbmV0X3E1XzBfbWF0bXVsX3JtLF9za2FpbmV0X3E1XzFfbWF0bXVsLF9za2FpbmV0X3E1XzFfbWF0bXVsX3JtLF9za2FpbmV0X3E4XzBfbWF0bXVsLF9za2FpbmV0X3E4XzBfbWF0bXVsX3JtLF9za2FpbmV0X3E0a19tYXRtdWwsX3NrYWluZXRfcTRrX21hdG11bF9ybSxfc2thaW5ldF9xNWtfbWF0bXVsLF9za2FpbmV0X3E1a19tYXRtdWxfcm0sX3NrYWluZXRfcTZrX21hdG11bCxfc2thaW5ldF9xNmtfbWF0bXVsX3JtLF9fZW1zY3JpcHRlbl90bHNfaW5pdCxfcHRocmVhZF9zZWxmLF9fZW1zY3JpcHRlbl90aHJlYWRfaW5pdCxfX2Vtc2NyaXB0ZW5fdGhyZWFkX2NyYXNoZWQsX19lbXNjcmlwdGVuX3J1bl9qc19vbl9tYWluX3RocmVhZCxfX2Vtc2NyaXB0ZW5fdGhyZWFkX2ZyZWVfZGF0YSxfX2Vtc2NyaXB0ZW5fdGhyZWFkX2V4aXQsX19lbXNjcmlwdGVuX2NoZWNrX21haWxib3gsX2Vtc2NyaXB0ZW5fc3RhY2tfc2V0X2xpbWl0cyxfX2Vtc2NyaXB0ZW5fc3RhY2tfcmVzdG9yZSxfX2Vtc2NyaXB0ZW5fc3RhY2tfYWxsb2MsX2Vtc2NyaXB0ZW5fc3RhY2tfZ2V0X2N1cnJlbnQ7ZnVuY3Rpb24gYXNzaWduV2FzbUV4cG9ydHMod2FzbUV4cG9ydHMpe01vZHVsZVsiX3NrYWluZXRfZnAzMl9tYXRtdWwiXT1fc2thaW5ldF9mcDMyX21hdG11bD13YXNtRXhwb3J0c1sicCJdO01vZHVsZVsiX3NrYWluZXRfZnAzMl9tYXRtdWxfd3QiXT1fc2thaW5ldF9mcDMyX21hdG11bF93dD13YXNtRXhwb3J0c1siciJdO01vZHVsZVsiX3NrYWluZXRfYmYxNl9tYXRtdWwiXT1fc2thaW5ldF9iZjE2X21hdG11bD13YXNtRXhwb3J0c1sicyJdO01vZHVsZVsiX3NrYWluZXRfZnAxNl9tYXRtdWwiXT1fc2thaW5ldF9mcDE2X21hdG11bD13YXNtRXhwb3J0c1sidCJdO01vZHVsZVsiX3NrYWluZXRfcTRfMF9tYXRtdWwiXT1fc2thaW5ldF9xNF8wX21hdG11bD13YXNtRXhwb3J0c1sidSJdO01vZHVsZVsiX3NrYWluZXRfcTRfMF9tYXRtdWxfcm0iXT1fc2thaW5ldF9xNF8wX21hdG11bF9ybT13YXNtRXhwb3J0c1sidiJdO01vZHVsZVsiX3NrYWluZXRfcTVfMF9tYXRtdWwiXT1fc2thaW5ldF9xNV8wX21hdG11bD13YXNtRXhwb3J0c1sidyJdO01vZHVsZVsiX21hbGxvYyJdPV9tYWxsb2M9d2FzbUV4cG9ydHNbIngiXTtNb2R1bGVbIl9mcmVlIl09X2ZyZWU9d2FzbUV4cG9ydHNbInkiXTtNb2R1bGVbIl9za2FpbmV0X3E1XzBfbWF0bXVsX3JtIl09X3NrYWluZXRfcTVfMF9tYXRtdWxfcm09d2FzbUV4cG9ydHNbInoiXTtNb2R1bGVbIl9za2FpbmV0X3E1XzFfbWF0bXVsIl09X3NrYWluZXRfcTVfMV9tYXRtdWw9d2FzbUV4cG9ydHNbIkEiXTtNb2R1bGVbIl9za2FpbmV0X3E1XzFfbWF0bXVsX3JtIl09X3NrYWluZXRfcTVfMV9tYXRtdWxfcm09d2FzbUV4cG9ydHNbIkIiXTtNb2R1bGVbIl9za2FpbmV0X3E4XzBfbWF0bXVsIl09X3NrYWluZXRfcThfMF9tYXRtdWw9d2FzbUV4cG9ydHNbIkMiXTtNb2R1bGVbIl9za2FpbmV0X3E4XzBfbWF0bXVsX3JtIl09X3NrYWluZXRfcThfMF9tYXRtdWxfcm09d2FzbUV4cG9ydHNbIkQiXTtNb2R1bGVbIl9za2FpbmV0X3E0a19tYXRtdWwiXT1fc2thaW5ldF9xNGtfbWF0bXVsPXdhc21FeHBvcnRzWyJFIl07TW9kdWxlWyJfc2thaW5ldF9xNGtfbWF0bXVsX3JtIl09X3NrYWluZXRfcTRrX21hdG11bF9ybT13YXNtRXhwb3J0c1siRiJdO01vZHVsZVsiX3NrYWluZXRfcTVrX21hdG11bCJdPV9za2FpbmV0X3E1a19tYXRtdWw9d2FzbUV4cG9ydHNbIkciXTtNb2R1bGVbIl9za2FpbmV0X3E1a19tYXRtdWxfcm0iXT1fc2thaW5ldF9xNWtfbWF0bXVsX3JtPXdhc21FeHBvcnRzWyJIIl07TW9kdWxlWyJfc2thaW5ldF9xNmtfbWF0bXVsIl09X3NrYWluZXRfcTZrX21hdG11bD13YXNtRXhwb3J0c1siSSJdO01vZHVsZVsiX3NrYWluZXRfcTZrX21hdG11bF9ybSJdPV9za2FpbmV0X3E2a19tYXRtdWxfcm09d2FzbUV4cG9ydHNbIkoiXTtfX2Vtc2NyaXB0ZW5fdGxzX2luaXQ9d2FzbUV4cG9ydHNbIksiXTtfcHRocmVhZF9zZWxmPXdhc21FeHBvcnRzWyJMIl07X19lbXNjcmlwdGVuX3RocmVhZF9pbml0PXdhc21FeHBvcnRzWyJNIl07X19lbXNjcmlwdGVuX3RocmVhZF9jcmFzaGVkPXdhc21FeHBvcnRzWyJOIl07X19lbXNjcmlwdGVuX3J1bl9qc19vbl9tYWluX3RocmVhZD13YXNtRXhwb3J0c1siTyJdO19fZW1zY3JpcHRlbl90aHJlYWRfZnJlZV9kYXRhPXdhc21FeHBvcnRzWyJQIl07X19lbXNjcmlwdGVuX3RocmVhZF9leGl0PXdhc21FeHBvcnRzWyJRIl07X19lbXNjcmlwdGVuX2NoZWNrX21haWxib3g9d2FzbUV4cG9ydHNbIlIiXTtfZW1zY3JpcHRlbl9zdGFja19zZXRfbGltaXRzPXdhc21FeHBvcnRzWyJTIl07X19lbXNjcmlwdGVuX3N0YWNrX3Jlc3RvcmU9d2FzbUV4cG9ydHNbIlQiXTtfX2Vtc2NyaXB0ZW5fc3RhY2tfYWxsb2M9d2FzbUV4cG9ydHNbIlUiXTtfZW1zY3JpcHRlbl9zdGFja19nZXRfY3VycmVudD13YXNtRXhwb3J0c1siViJdfXZhciB3YXNtSW1wb3J0cztmdW5jdGlvbiBhc3NpZ25XYXNtSW1wb3J0cygpe3dhc21JbXBvcnRzPXtnOl9fX3B0aHJlYWRfY3JlYXRlX2pzLGs6X19lbXNjcmlwdGVuX2luaXRfbWFpbl90aHJlYWRfanMsbjpfX2Vtc2NyaXB0ZW5fbm90aWZ5X21haWxib3hfcG9zdG1lc3NhZ2UsbDpfX2Vtc2NyaXB0ZW5fcmVjZWl2ZV9vbl9tYWluX3RocmVhZF9qcyxjOl9fZW1zY3JpcHRlbl90aHJlYWRfY2xlYW51cCxqOl9fZW1zY3JpcHRlbl90aHJlYWRfbWFpbGJveF9hd2FpdCxpOl9fZW1zY3JpcHRlbl90aHJlYWRfc2V0X3N0cm9uZ3JlZixlOl9lbXNjcmlwdGVuX2NoZWNrX2Jsb2NraW5nX2FsbG93ZWQsaDpfZW1zY3JpcHRlbl9leGl0X3dpdGhfbGl2ZV9ydW50aW1lLGI6X2Vtc2NyaXB0ZW5fZ2V0X25vdyxtOl9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwLGY6X2V4aXQsZDpfZmRfd3JpdGUsYTp3YXNtTWVtb3J5fX1mdW5jdGlvbiBhcHBseVNpZ25hdHVyZUNvbnZlcnNpb25zKHdhc21FeHBvcnRzKXt3YXNtRXhwb3J0cz1PYmplY3QuYXNzaWduKHt9LHdhc21FeHBvcnRzKTt2YXIgbWFrZVdyYXBwZXJfcHA9Zj0+YTA9PmYoYTApPj4+MDt2YXIgbWFrZVdyYXBwZXJfcD1mPT4oKT0+ZigpPj4+MDt3YXNtRXhwb3J0c1sieCJdPW1ha2VXcmFwcGVyX3BwKHdhc21FeHBvcnRzWyJ4Il0pO3dhc21FeHBvcnRzWyJMIl09bWFrZVdyYXBwZXJfcCh3YXNtRXhwb3J0c1siTCJdKTt3YXNtRXhwb3J0c1siVSJdPW1ha2VXcmFwcGVyX3BwKHdhc21FeHBvcnRzWyJVIl0pO3dhc21FeHBvcnRzWyJWIl09bWFrZVdyYXBwZXJfcCh3YXNtRXhwb3J0c1siViJdKTtyZXR1cm4gd2FzbUV4cG9ydHN9ZnVuY3Rpb24gcnVuKCl7aWYocnVuRGVwZW5kZW5jaWVzPjApe2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1ydW47cmV0dXJufWlmKEVOVklST05NRU5UX0lTX1BUSFJFQUQpe3JlYWR5UHJvbWlzZVJlc29sdmU/LihNb2R1bGUpO2luaXRSdW50aW1lKCk7cmV0dXJufXByZVJ1bigpO2lmKHJ1bkRlcGVuZGVuY2llcz4wKXtkZXBlbmRlbmNpZXNGdWxmaWxsZWQ9cnVuO3JldHVybn1mdW5jdGlvbiBkb1J1bigpe01vZHVsZVsiY2FsbGVkUnVuIl09dHJ1ZTtpZihBQk9SVClyZXR1cm47aW5pdFJ1bnRpbWUoKTtyZWFkeVByb21pc2VSZXNvbHZlPy4oTW9kdWxlKTtNb2R1bGVbIm9uUnVudGltZUluaXRpYWxpemVkIl0/LigpO3Bvc3RSdW4oKX1pZihNb2R1bGVbInNldFN0YXR1cyJdKXtNb2R1bGVbInNldFN0YXR1cyJdKCJSdW5uaW5nLi4uIik7c2V0VGltZW91dCgoKT0+e3NldFRpbWVvdXQoKCk9Pk1vZHVsZVsic2V0U3RhdHVzIl0oIiIpLDEpO2RvUnVuKCl9LDEpfWVsc2V7ZG9SdW4oKX19dmFyIHdhc21FeHBvcnRzO2lmKCFFTlZJUk9OTUVOVF9JU19QVEhSRUFEKXt3YXNtRXhwb3J0cz1hd2FpdCAoY3JlYXRlV2FzbSgpKTtydW4oKX1pZihydW50aW1lSW5pdGlhbGl6ZWQpe21vZHVsZVJ0bj1Nb2R1bGV9ZWxzZXttb2R1bGVSdG49bmV3IFByb21pc2UoKHJlc29sdmUscmVqZWN0KT0+e3JlYWR5UHJvbWlzZVJlc29sdmU9cmVzb2x2ZTtyZWFkeVByb21pc2VSZWplY3Q9cmVqZWN0fSl9CjtyZXR1cm4gbW9kdWxlUnRufWV4cG9ydCBkZWZhdWx0IGNyZWF0ZVNrYWluZXRLZXJuZWxzO3ZhciBpc1B0aHJlYWQ9Z2xvYmFsVGhpcy5zZWxmPy5uYW1lPy5zdGFydHNXaXRoKCJlbS1wdGhyZWFkIik7dmFyIGlzTm9kZT10eXBlb2YgcHJvY2Vzcz09Im9iamVjdCImJnByb2Nlc3MudmVyc2lvbnM/Lm5vZGUmJnByb2Nlc3MudHlwZSE9InJlbmRlcmVyIjtpZihpc05vZGUpaXNQdGhyZWFkPShhd2FpdCBpbXBvcnQoIndvcmtlcl90aHJlYWRzIikpLndvcmtlckRhdGE9PT0iZW0tcHRocmVhZCI7aXNQdGhyZWFkJiZjcmVhdGVTa2FpbmV0S2VybmVscygpOwo=" + const val MT_WASM: String = "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NgIAIAFBHGtBADYCACACIABBBHFBGHIiAmsiAUEgSQ0AIAAgAmohAANAIABCADcDGCAAQgA3AxAgAEIANwMIIABCADcDACAAQSBqIQAgAUEgayIBQR9LDQALCwvyAQEFfyMAQRBrIgMkACADQQA2AgwgAEEgaiIGEBogACgCFCICQQBHIQUCQCABRQ0AIAJFDQADQAJAIAJBCGpBAEEB/kgCAARAIAMgAygCDEEBajYCDCACIANBDGo2AhAMAQsgBCACIAQbIQQgAUEBayEBCyACKAIAIgJBAEchBSABRQ0BIAINAAsLAkAgBQRAIAIoAgQiAQRAIAFBADYCAAsgAkEANgIEDAELIABBADYCBAsgACACNgIUIAYQGSADKAIMIgIEQANAIANBDGpBACACEBMgAygCDCICDQALCyAEBEAgBEEMahAZCyADQRBqJAALYgEBfwJAIwUEQEGEDf4QAgANASMBIgAtAARFBEAgAEEBOgAEQZwLEA4aQZwLIwMQNiEAQZwLEA0CQCAARQ0AIAAoAiANACAAECcLIwFBADoABAsLDwtBhA3+EAIAEAcQBgALhwEBA38jAEEgayIBJAACQCAAKAIIRQRAIABBEGoiAhAOGiAAQQI2AgwgAhANIABBKGoQKAwBCyAAKAIYBEAgACgCECECIAAoAgwgASAANgIcIAEgADYCECABQRc2AhggAUEcNgIUIAEgASkCFDcDCCACIAFBCGoQHA0BCyAAEBYLIAFBIGokAAuCAQECfyAAKAIIRQRAIABBEGoQLQJAIABBKGoiACgCAEUNACAAKAIMRQ0AIABBDGoiAUGAgICAeP4zAgAaIABBCGoiAkEB/h4CABogAkH/////BxAPIAAoAgwiAEH/////B3FFDQADQCABQQAgABATIAEoAgAiAEH/////B3ENAAsLCwtlAQJ/IAAgACgCWEYEQCAAQgA3AlhBwAsoAgBBABAgDwsjAygCSEHACygCACIBQQJ0aigCACICIABGBEAgASACKAJYECALIAAoAlwiAiAAKAJYIgE2AlggASACNgJcIABCADcCWAueCQEOfwJAIAAgARA2IgJFBEAgACgCHCICIAAoAiBGBEACfyACQQF0QQEgAhsiD0ECdCEJIAAoAhgiDEUEQCAJEBEMAQsgCUFATwRAIwFBMDYCAEEADAELAkBBtBkt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" } diff --git a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmCpuOps.kt b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmCpuOps.kt index ccc3d7f8f..eb1df89f0 100644 --- a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmCpuOps.kt +++ b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsMain/kotlin/sk/ainet/exec/wasm/WasmCpuOps.kt @@ -13,7 +13,7 @@ import sk.ainet.lang.types.FP32 /** * The browser tier's `TensorOps` (SKEEP-007 §T1): [DefaultCpuOpsBase] with the dense FP32 matmuls - * routed through the SIMD128 sidecar. Packed weights need no override — they reach the pack through + * (`x · Wᵀ` and `A · B`) routed through the SIMD128 sidecar. Packed weights need no override — they reach the pack through * `KernelDispatch` like on every other tier. Everything else is the common scalar implementation, * and so is everything here while the sidecar is not ready. */ @@ -28,6 +28,33 @@ public class WasmCpuOps( /** The sidecar computes `x · Wᵀ` from the weight's rows itself; no Kotlin-side row-dot and no transposed copy. */ override fun preferDirectWeightTransposed(): Boolean = false + /** + * Dense `A(m,k) · B(k,n)` on heap FP32 operands runs the sidecar GEMM. The common implementation + * serves this shape with its own `[k, n]` loop before it consults the registry, so without this + * override the SIMD128 kernel was reachable only through `KernelDispatch` (batched or view + * operands) and a plain 2-D matmul stayed at scalar speed. Both operands are staged per call: + * `B` here is not necessarily a parameter (attention scores, projections of activations), so + * nothing is kept resident. A packed weight is not `FloatArrayTensorData` and keeps its path. + */ + @Suppress("UNCHECKED_CAST") + override fun matmul(a: Tensor, b: Tensor): Tensor { + if (WasmKernels.isReady && a.rank == 2 && b.rank == 2 && a.dtype == FP32::class && b.dtype == FP32::class) { + val ad = a.data as? FloatArrayTensorData<*> + val bd = b.data as? FloatArrayTensorData<*> + if (ad != null && bd != null && untransposedWeight(b) == null) { + val m = a.shape[0] + val k = a.shape[1] + val n = b.shape[1] + require(k == b.shape[0]) { "Matrix multiplication shape mismatch: ${a.shape} vs ${b.shape}" } + val out = FloatArray(m * n) + if (m > 0 && n > 0) WasmFp32MatmulKernel.matmul(ad.buffer, 0, k, bd.buffer, 0, n, out, 0, n, m, n, k) + val outData = dataFactory.adoptFloatArray(Shape(m, n), a.dtype, out) as TensorData + return newTensor(outData, a.dtype, a, b) + } + } + return super.matmul(a, b) + } + @Suppress("UNCHECKED_CAST") override fun matmulWeightTransposed(x: Tensor, weight: Tensor): Tensor { if (WasmKernels.isReady && weight.shape.rank == 2 && x.rank >= 1 && x.dtype == FP32::class && weight.dtype == FP32::class) { diff --git a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt index ae1587591..31c96f6eb 100644 --- a/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt +++ b/skainet-backends/skainet-backend-wasm-simd/src/wasmJsTest/kotlin/sk/ainet/exec/wasm/WasmSimdParityTest.kt @@ -8,6 +8,11 @@ import sk.ainet.backend.api.kernel.NoSuchKernelException import sk.ainet.context.DirectCpuExecutionContext import sk.ainet.exec.kernel.ScalarBf16MatmulKernel import sk.ainet.exec.kernel.ScalarFp16MatmulKernel +import sk.ainet.exec.kernel.ScalarQ4_KMatmulKernel +import sk.ainet.exec.kernel.ScalarQ5_0MatmulKernel +import sk.ainet.exec.kernel.ScalarQ5_1MatmulKernel +import sk.ainet.exec.kernel.ScalarQ5_KMatmulKernel +import sk.ainet.exec.kernel.ScalarQ6_KMatmulKernel import sk.ainet.exec.tensor.ops.DefaultCpuOps import sk.ainet.lang.types.Bf16Codec import sk.ainet.lang.types.Fp16Codec @@ -20,6 +25,8 @@ import sk.ainet.lang.tensor.data.TensorData import sk.ainet.lang.tensor.matmulWeightTransposed import sk.ainet.lang.types.FP32 import kotlin.math.abs +import kotlin.math.sqrt +import kotlin.random.Random import kotlin.test.AfterTest import kotlin.test.Test import kotlin.test.assertEquals @@ -36,6 +43,8 @@ import kotlin.test.assertTrue * sums differ from the sequential scalar accumulation in the last bits, so comparisons are * relative-tolerance, as the JVM Panama and native parity tests are. */ +private typealias PackedMatmul = (FloatArray, ByteArray, Int, Int, FloatArray) -> Unit + class WasmSimdParityTest { private fun pseudo(n: Int, seed: Int, scale: Float = 1f): FloatArray { @@ -139,6 +148,86 @@ class WasmSimdParityTest { assertEquals(false, KernelStrictness.isEnabled()) } + /** + * Random packed bytes with the FP16 scale slots forced to 1.0 (0x3C00) so magnitudes stay + * finite — the fixture the JVM native parity tests use. [exact] formats accumulate in FP32 on + * both sides and agree to lane-sum tolerance; the K-quant int8 kernels (Q4_K, Q6_K) quantize the + * activation to Q8 first, so they are gated on an aggregate relative RMS error like the JVM tests. + */ + private fun packedParity( + what: String, blockSize: Int, bytesPerBlock: Int, scaleSlots: IntArray, inputDim: Int, outputDim: Int, + exact: Boolean, scalar: PackedMatmul, wasm: PackedMatmul, + ) { + val numBlocks = (inputDim / blockSize) * outputDim + val rng = Random(what.hashCode()) + val packed = ByteArray(numBlocks * bytesPerBlock).also { rng.nextBytes(it) } + for (block in 0 until numBlocks) { + for (slot in scaleSlots) { + packed[block * bytesPerBlock + slot] = 0x00 + packed[block * bytesPerBlock + slot + 1] = 0x3C + } + } + val input = FloatArray(inputDim) { rng.nextFloat() - 0.5f } + val ref = FloatArray(outputDim) + val got = FloatArray(outputDim) + scalar(input, packed, inputDim, outputDim, ref) + wasm(input, packed, inputDim, outputDim, got) + if (exact) { + assertClose(ref, got, what, rel = 1e-4f) + } else { + var err = 0.0; var sig = 0.0 + for (o in 0 until outputDim) { err += (ref[o] - got[o]).toDouble().let { it * it }; sig += ref[o].toDouble().let { it * it } } + val relRms = sqrt(err / outputDim) / (sqrt(sig / outputDim) + 1e-9) + assertTrue(relRms < 0.03, "$what: relRms=$relRms over $outputDim rows") + } + } + + @Test + fun `K-quant and Q5 weights run on the sidecar and match the scalar kernels`() = runTest { + WasmSimd.install() + val p = checkNotNull(KernelRegistry.bestAvailable()) + assertEquals("wasm-simd128", p.name) + // 37 rows: an odd count, so a threaded row split (none below 512) is not what is under test; + // two or three blocks per row cover the block-outer accumulation and the per-row carry. + packedParity("q4_k", 256, 144, intArrayOf(0, 2), 512, 37, exact = false, + { i, w, id, od, o -> ScalarQ4_KMatmulKernel.matmul(i, 0, w, 0, id, od, o, 0) }, + { i, w, id, od, o -> checkNotNull(p.matmulQ4K()).matmul(i, 0, w, 0, id, od, o, 0) }) + packedParity("q6_k", 256, 210, intArrayOf(208), 512, 37, exact = false, + { i, w, id, od, o -> ScalarQ6_KMatmulKernel.matmul(i, 0, w, 0, id, od, o, 0) }, + { i, w, id, od, o -> checkNotNull(p.matmulQ6K()).matmul(i, 0, w, 0, id, od, o, 0) }) + packedParity("q5_k", 256, 176, intArrayOf(0, 2), 512, 37, exact = true, + { i, w, id, od, o -> ScalarQ5_KMatmulKernel.matmul(i, 0, w, 0, id, od, o, 0) }, + { i, w, id, od, o -> checkNotNull(p.matmulQ5K()).matmul(i, 0, w, 0, id, od, o, 0) }) + packedParity("q5_0", 32, 22, intArrayOf(0), 96, 37, exact = true, + { i, w, id, od, o -> ScalarQ5_0MatmulKernel.matmul(i, 0, w, 0, id, od, o, 0) }, + { i, w, id, od, o -> checkNotNull(p.matmulQ5_0()).matmul(i, 0, w, 0, id, od, o, 0) }) + packedParity("q5_1", 32, 24, intArrayOf(0, 2), 96, 37, exact = true, + { i, w, id, od, o -> ScalarQ5_1MatmulKernel.matmul(i, 0, w, 0, id, od, o, 0) }, + { i, w, id, od, o -> checkNotNull(p.matmulQ5_1()).matmul(i, 0, w, 0, id, od, o, 0) }) + } + + @Test + fun `dense GEMM through the ops layer runs on the sidecar for every tile shape`() = runTest { + val scalar = DirectCpuExecutionContext() + WasmSimd.install() + val fast = DirectCpuExecutionContext() + assertIs(fast.ops) + // Full 4×8 tiles, a 1-row remainder, a 6-column remainder and a k past one 256-block. + for ((m, n, k) in listOf(Triple(9, 70, 300), Triple(1, 8, 5), Triple(4, 3, 1), Triple(5, 16, 256))) { + val x = pseudo(m * k, m + n) + val b = pseudo(k * n, k) + val ref = scalar.ops.matmul( + scalar.fromFloatArray(Shape(m, k), FP32::class, x), + scalar.fromFloatArray(Shape(k, n), FP32::class, b), + ).data.copyToFloatArray() + val got = fast.ops.matmul( + fast.fromFloatArray(Shape(m, k), FP32::class, x), + fast.fromFloatArray(Shape(k, n), FP32::class, b), + ).data.copyToFloatArray() + assertClose(ref, got, "gemm $m×$k·$k×$n") + } + } + @Test fun `row-major Q8_0 and Q4_0 weights match the scalar lane and run on the pack`() = runTest { val scalar = DirectCpuExecutionContext() @@ -186,8 +275,8 @@ class WasmSimdParityTest { assertClose(refWt, fast.ops.matmulWeightTransposed(xf, wf).data.copyToFloatArray(), "x·Wᵀ") val rank1 = fast.fromFloatArray(Shape(k), FP32::class, x.copyOfRange(0, k)) assertClose(refWt.copyOfRange(0, n), fast.ops.matmulWeightTransposed(rank1, wf).data.copyToFloatArray(), "rank-1 x·Wᵀ") - // The dense GEMM goes through KernelDispatch → Fp32ViewMatmulKernel(WasmFp32MatmulKernel) for - // the registry path; the common [k, n] loop still serves the heap fast path, so exercise the + // The dense GEMM runs the sidecar through the WasmCpuOps override (heap operands) and through + // KernelDispatch → Fp32ViewMatmulKernel(WasmFp32MatmulKernel) for view operands; exercise the // provider kernel directly as well. assertClose(refMm, fast.ops.matmul(xf, bf).data.copyToFloatArray(), "matmul") val direct = FloatArray(m * n)