semantifold 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -12
- package/build/index.js +2 -2
- package/build/src/acceptance.d.ts +10 -0
- package/build/src/acceptance.d.ts.map +1 -1
- package/build/src/acceptance.js +24 -5
- package/build/src/backends/c-runtime.d.ts +3 -0
- package/build/src/backends/c-runtime.d.ts.map +1 -0
- package/build/src/backends/c-runtime.js +151 -0
- package/build/src/backends/c-validation.d.ts +12 -0
- package/build/src/backends/c-validation.d.ts.map +1 -0
- package/build/src/backends/c-validation.js +85 -0
- package/build/src/backends/c.d.ts +31 -0
- package/build/src/backends/c.d.ts.map +1 -0
- package/build/src/backends/c.js +308 -0
- package/build/src/backends/cpp-runtime.d.ts +3 -0
- package/build/src/backends/cpp-runtime.d.ts.map +1 -0
- package/build/src/backends/cpp-runtime.js +99 -0
- package/build/src/backends/cpp-validation.d.ts +9 -0
- package/build/src/backends/cpp-validation.d.ts.map +1 -0
- package/build/src/backends/cpp-validation.js +74 -0
- package/build/src/backends/cpp.d.ts +16 -0
- package/build/src/backends/cpp.d.ts.map +1 -0
- package/build/src/backends/cpp.js +285 -0
- package/build/src/backends/csharp.d.ts +20 -0
- package/build/src/backends/csharp.d.ts.map +1 -0
- package/build/src/backends/csharp.js +259 -0
- package/build/src/backends/go.d.ts +20 -0
- package/build/src/backends/go.d.ts.map +1 -0
- package/build/src/backends/go.js +374 -0
- package/build/src/backends/identifiers.d.ts +12 -0
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +71 -2
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +9 -1
- package/build/src/backends/native-validation.d.ts +9 -0
- package/build/src/backends/native-validation.d.ts.map +1 -0
- package/build/src/backends/native-validation.js +59 -0
- package/build/src/backends/ordered-expressions.d.ts +74 -0
- package/build/src/backends/ordered-expressions.d.ts.map +1 -0
- package/build/src/backends/ordered-expressions.js +159 -0
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +7 -2
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +59 -14
- package/build/src/frontends/c-parser.d.ts +20 -0
- package/build/src/frontends/c-parser.d.ts.map +1 -0
- package/build/src/frontends/c-parser.js +14 -0
- package/build/src/frontends/c.d.ts +220 -0
- package/build/src/frontends/c.d.ts.map +1 -0
- package/build/src/frontends/c.js +750 -0
- package/build/src/frontends/cpp-parser.d.ts +11 -0
- package/build/src/frontends/cpp-parser.d.ts.map +1 -0
- package/build/src/frontends/cpp-parser.js +15 -0
- package/build/src/frontends/cpp.d.ts +227 -0
- package/build/src/frontends/cpp.d.ts.map +1 -0
- package/build/src/frontends/cpp.js +784 -0
- package/build/src/frontends/csharp.d.ts +14 -0
- package/build/src/frontends/csharp.d.ts.map +1 -0
- package/build/src/frontends/csharp.js +708 -0
- package/build/src/frontends/go.d.ts +15 -0
- package/build/src/frontends/go.d.ts.map +1 -0
- package/build/src/frontends/go.js +712 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +16 -1
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +51 -2
- package/build/src/mapping.js +2 -2
- package/build/src/semantic/provenance.js +3 -3
- package/build/src/semantic/types.d.ts +4 -4
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +3 -3
- package/build/src/subprocess.d.ts +10 -1
- package/build/src/subprocess.d.ts.map +1 -1
- package/build/src/subprocess.js +29 -3
- package/build/src/toolchains.d.ts +24 -0
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +6 -2
- package/docs/architecture.md +20 -6
- package/docs/c.md +60 -0
- package/docs/cpp.md +61 -0
- package/docs/goals.md +4 -2
- package/docs/language-support.md +27 -8
- package/docs/parser-qualification.md +153 -4
- package/docs/plans/2026-09-05-standard-library-portability.md +46 -0
- package/docs/source-maps.md +11 -5
- package/docs/standard-library-portability.md +190 -0
- package/docs/testing.md +113 -4
- package/index.js +1 -1
- package/node_modules/node-addon-api/LICENSE.md +9 -0
- package/node_modules/node-addon-api/README.md +95 -0
- package/node_modules/node-addon-api/common.gypi +21 -0
- package/node_modules/node-addon-api/except.gypi +25 -0
- package/node_modules/node-addon-api/index.js +14 -0
- package/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
- package/node_modules/node-addon-api/napi-inl.h +7250 -0
- package/node_modules/node-addon-api/napi.h +3463 -0
- package/node_modules/node-addon-api/node_addon_api.gyp +42 -0
- package/node_modules/node-addon-api/node_api.gyp +9 -0
- package/node_modules/node-addon-api/noexcept.gypi +26 -0
- package/node_modules/node-addon-api/nothing.c +0 -0
- package/node_modules/node-addon-api/package-support.json +21 -0
- package/node_modules/node-addon-api/package.json +481 -0
- package/node_modules/node-addon-api/tools/README.md +73 -0
- package/node_modules/node-addon-api/tools/check-napi.js +99 -0
- package/node_modules/node-addon-api/tools/clang-format.js +71 -0
- package/node_modules/node-addon-api/tools/conversion.js +301 -0
- package/node_modules/node-gyp-build/LICENSE +21 -0
- package/node_modules/node-gyp-build/README.md +58 -0
- package/node_modules/node-gyp-build/SECURITY.md +5 -0
- package/node_modules/node-gyp-build/bin.js +84 -0
- package/node_modules/node-gyp-build/build-test.js +19 -0
- package/node_modules/node-gyp-build/index.js +6 -0
- package/node_modules/node-gyp-build/node-gyp-build.js +207 -0
- package/node_modules/node-gyp-build/optional.js +7 -0
- package/node_modules/node-gyp-build/package.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/LICENSE +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +7 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/README.md +90 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/binding.gyp +79 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/index.js +895 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/package.json +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.cc +106 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.cc +1056 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.cc +298 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.cc +383 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.h +39 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.cc +307 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/tree-sitter.d.ts +211 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +221 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +299 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +419 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +14 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +774 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2151 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +230 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4134 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1060 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +382 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +165 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +714 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +50 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +23 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1294 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1823 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/README.md +18 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/binding.gyp +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/grammar.js +1470 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/package.json +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/highlights.scm +81 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/tags.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/grammar.json +9735 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/node-types.json +4614 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/parser.c +119615 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter-c.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/README.md +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/grammar.js +1436 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/package.json +61 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/highlights.scm +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/injections.scm +3 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/tags.scm +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/grammar.json +17084 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/node-types.json +7997 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/parser.c +530368 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/scanner.c +148 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter-cpp.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter.json +55 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +152 -0
- package/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/tree-sitter/README.md +128 -0
- package/node_modules/tree-sitter/binding.gyp +88 -0
- package/node_modules/tree-sitter/index.js +950 -0
- package/node_modules/tree-sitter/package.json +76 -0
- package/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/tree-sitter/src/language.cc +105 -0
- package/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/tree-sitter/src/node.cc +1088 -0
- package/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/tree-sitter/src/parser.cc +332 -0
- package/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/tree-sitter/src/query.cc +425 -0
- package/node_modules/tree-sitter/src/query.h +40 -0
- package/node_modules/tree-sitter/src/tree.cc +316 -0
- package/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/tree-sitter/tree-sitter.d.ts +1083 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1478 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +291 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +523 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +483 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +54 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +12 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +875 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2297 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +286 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +241 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4347 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +912 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1034 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +399 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +170 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +716 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/ts_assert.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +75 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +24 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +137 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1314 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1937 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/package.json +21 -5
- package/src/acceptance.js +25 -4
- package/src/backends/c-runtime.js +151 -0
- package/src/backends/c-validation.js +83 -0
- package/src/backends/c.js +308 -0
- package/src/backends/cpp-runtime.js +99 -0
- package/src/backends/cpp-validation.js +70 -0
- package/src/backends/cpp.js +285 -0
- package/src/backends/csharp.js +270 -0
- package/src/backends/go.js +383 -0
- package/src/backends/identifiers.js +72 -1
- package/src/backends/index.js +7 -0
- package/src/backends/native-validation.js +64 -0
- package/src/backends/ordered-expressions.js +161 -0
- package/src/backends/scalars.js +7 -1
- package/src/backends/shared.js +56 -12
- package/src/frontends/c-parser.js +17 -0
- package/src/frontends/c.js +780 -0
- package/src/frontends/cpp-parser.js +18 -0
- package/src/frontends/cpp.js +816 -0
- package/src/frontends/csharp.js +759 -0
- package/src/frontends/go.js +770 -0
- package/src/frontends/scalars.js +15 -0
- package/src/language-registry.js +52 -1
- package/src/mapping.js +1 -1
- package/src/semantic/provenance.js +2 -2
- package/src/semantic/types.js +2 -2
- package/src/subprocess.js +31 -2
- package/src/toolchains.js +5 -1
|
@@ -0,0 +1,784 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { generateCpp } from "../backends/cpp.js";
|
|
3
|
+
import { OrderedExpressionPlanner } from "../backends/ordered-expressions.js";
|
|
4
|
+
import { maximumCppSourceLength } from "../backends/cpp-validation.js";
|
|
5
|
+
import { validateNativeGraph } from "../backends/native-validation.js";
|
|
6
|
+
import { cppRuntime } from "../backends/cpp-runtime.js";
|
|
7
|
+
import { validateBackendModule } from "../backends/shared.js";
|
|
8
|
+
import { isCppIdentifier } from "../backends/identifiers.js";
|
|
9
|
+
import { parseCppCst } from "./cpp-parser.js";
|
|
10
|
+
import { missingType, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
|
|
11
|
+
import { createCoordinateIndex, indexedPointAt } from "../semantic/location.js";
|
|
12
|
+
import { withAdaptedOperation } from "../semantic/operators.js";
|
|
13
|
+
import { withParserRanges } from "../semantic/provenance.js";
|
|
14
|
+
import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
|
|
15
|
+
import { validateParsedModule } from "../semantic/validate.js";
|
|
16
|
+
import { sourceScalarType } from "./scalars.js";
|
|
17
|
+
/** @typedef {import("./cpp-parser.js").CstNode} CstNode */
|
|
18
|
+
/** @typedef {import("../semantic/types.js").Expression} Expression */
|
|
19
|
+
/** @typedef {import("../semantic/types.js").Statement} Statement */
|
|
20
|
+
const binaryOperations = new Map([
|
|
21
|
+
["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
|
|
22
|
+
["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
|
|
23
|
+
["&&", "And"], ["||", "Or"]
|
|
24
|
+
]);
|
|
25
|
+
const helpers = new Map([
|
|
26
|
+
["semantifold_integer_add", "PhpAdd"], ["semantifold_integer_subtract", "Subtract"],
|
|
27
|
+
["semantifold_integer_multiply", "Multiply"], ["semantifold_string_concat", "StringConcat"],
|
|
28
|
+
["semantifold_string_equal", "StringEqual"], ["semantifold_string_not_equal", "StringNotEqual"]
|
|
29
|
+
]);
|
|
30
|
+
/** Strict field-and-token consumer for the private frozen CPP CST. */
|
|
31
|
+
export class CppReader {
|
|
32
|
+
/**
|
|
33
|
+
* Owns source content and its coordinate index, never native parser handles.
|
|
34
|
+
* @param {string} filename - Original filename.
|
|
35
|
+
* @param {string} source - Exact original source.
|
|
36
|
+
*/
|
|
37
|
+
constructor(filename, source) {
|
|
38
|
+
this.filename = filename;
|
|
39
|
+
this.source = source;
|
|
40
|
+
this.coordinates = createCoordinateIndex(source);
|
|
41
|
+
this.generated = false;
|
|
42
|
+
/** @type {Map<string, Expression> | undefined} */
|
|
43
|
+
this.temporaryExpressions = undefined;
|
|
44
|
+
/** @type {Set<string> | undefined} */
|
|
45
|
+
this.temporaryNames = undefined;
|
|
46
|
+
/** @type {Map<Statement, {node: CstNode, type: string}>} */
|
|
47
|
+
this.printTypes = new Map();
|
|
48
|
+
/** @type {Set<string>} */
|
|
49
|
+
this.declaredFunctions = new Set();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Locates one parser-owned range in UTF-16 coordinates.
|
|
53
|
+
* @param {CstNode} node - Parser node.
|
|
54
|
+
* @returns {import("../semantic/types.js").SourceLocation} Verified location.
|
|
55
|
+
*/
|
|
56
|
+
location(node) {
|
|
57
|
+
return { filename: this.filename, start: indexedPointAt(this.coordinates, node.startIndex), end: indexedPointAt(this.coordinates, node.endIndex) };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Reads only the spelling of an already recognized parser node.
|
|
61
|
+
* @param {CstNode} node - Parser node.
|
|
62
|
+
* @returns {string} Exact token spelling.
|
|
63
|
+
*/
|
|
64
|
+
text(node) {
|
|
65
|
+
return this.source.slice(node.startIndex, node.endIndex);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Rejects a located source-profile violation.
|
|
69
|
+
* @param {CstNode} node - Rejected node.
|
|
70
|
+
* @param {string} [detail] - Profile violation.
|
|
71
|
+
* @returns {never} Always throws.
|
|
72
|
+
*/
|
|
73
|
+
fail(node, detail = node.type) {
|
|
74
|
+
unsupportedSyntax("cpp", detail, this.location(node));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Traverses all edges before interpreting any source meaning.
|
|
78
|
+
* @param {CstNode} node - Current parser node.
|
|
79
|
+
* @param {number} [depth] - Bounded CST traversal depth.
|
|
80
|
+
* @returns {void}
|
|
81
|
+
*/
|
|
82
|
+
validateTree(node, depth = 0) {
|
|
83
|
+
if (depth > 512)
|
|
84
|
+
this.fail(node, "CPP CST exceeds the 512-level traversal limit");
|
|
85
|
+
for (const { node: child } of node.children)
|
|
86
|
+
this.validateTree(child, depth + 1);
|
|
87
|
+
if (node.error || node.missing || node.hasError) {
|
|
88
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "cpp", location: this.location(node), message: `CPP parser recovery at '${node.type}'.` });
|
|
89
|
+
}
|
|
90
|
+
if (node.extra && node.type != "comment")
|
|
91
|
+
this.fail(node, "unexpected extra parser child");
|
|
92
|
+
if ((node.type == "comment" || node.type == "string_content") && /\?\?[=/'()!<>-]/u.test(this.text(node))) {
|
|
93
|
+
this.fail(node, "trigraph preprocessing");
|
|
94
|
+
}
|
|
95
|
+
if (node.type == "comment") {
|
|
96
|
+
const text = this.text(node);
|
|
97
|
+
// A terminal CR belongs to ordinary CRLF; content after a bare CR is not a CPP line comment.
|
|
98
|
+
if (/\\(?:\r\n?|\n)/u.test(text) || text.startsWith("//") && /\r(?!\n|$)/u.test(text)) {
|
|
99
|
+
this.fail(node, "preprocessing-sensitive comment");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Separates harmless comments after every child has been validated.
|
|
105
|
+
* @param {CstNode} node - Parent node.
|
|
106
|
+
* @returns {CstNode[]} Ordered structural children.
|
|
107
|
+
*/
|
|
108
|
+
parts(node) {
|
|
109
|
+
return node.children.map(({ node: child }) => child).filter((child) => child.type != "comment");
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Requires one exact field rather than searching descendants.
|
|
113
|
+
* @param {CstNode} node - Field owner.
|
|
114
|
+
* @param {string} name - Field name.
|
|
115
|
+
* @returns {CstNode} Sole field child.
|
|
116
|
+
*/
|
|
117
|
+
field(node, name) {
|
|
118
|
+
const matches = node.children.filter(({ field }) => field == name);
|
|
119
|
+
if (matches.length != 1)
|
|
120
|
+
return this.fail(node, `expected one '${name}' field`);
|
|
121
|
+
return matches[0].node;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Consumes every structural child, including punctuation.
|
|
125
|
+
* @param {CstNode} node - Shape owner.
|
|
126
|
+
* @param {(CstNode | string)[]} expected - Ordered nodes or token kinds.
|
|
127
|
+
* @returns {void}
|
|
128
|
+
*/
|
|
129
|
+
shape(node, expected) {
|
|
130
|
+
const children = this.parts(node);
|
|
131
|
+
if (children.length != expected.length || children.some((child, index) => typeof expected[index] == "string" ? child.type != expected[index] : child !== expected[index]))
|
|
132
|
+
this.fail(node, `${node.type} child shape`);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Requires an ordinary caller identifier outside the protected namespace.
|
|
136
|
+
* @param {CstNode} node - Identifier token.
|
|
137
|
+
* @returns {string} Accepted spelling.
|
|
138
|
+
*/
|
|
139
|
+
identifier(node) {
|
|
140
|
+
const name = this.text(node);
|
|
141
|
+
if (node.type != "identifier" || !isCppIdentifier(name))
|
|
142
|
+
this.fail(node, "reserved or unsupported identifier");
|
|
143
|
+
return name;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Converts only the canonical scalar type spellings.
|
|
147
|
+
* @param {CstNode} node - Type token.
|
|
148
|
+
* @returns {import("../semantic/types.js").TypeReference} Semantic scalar.
|
|
149
|
+
*/
|
|
150
|
+
type(node) {
|
|
151
|
+
const spelling = node.type == "qualified_identifier" ? this.qualified(node) : this.text(node);
|
|
152
|
+
if (node.type != "qualified_identifier" && (node.type != "primitive_type" || spelling != "bool"))
|
|
153
|
+
this.fail(node, "scalar type shape");
|
|
154
|
+
const type = sourceScalarType("cpp", spelling, this.location(node));
|
|
155
|
+
if (!type)
|
|
156
|
+
return this.fail(node, "unsupported scalar type");
|
|
157
|
+
return type;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Reads exactly one std-qualified scalar name from CPP fields and punctuation.
|
|
161
|
+
* @param {CstNode} node - Qualified grammar node.
|
|
162
|
+
* @returns {string} Canonical qualified scalar spelling.
|
|
163
|
+
*/
|
|
164
|
+
qualified(node) {
|
|
165
|
+
const scope = this.field(node, "scope");
|
|
166
|
+
const name = this.field(node, "name");
|
|
167
|
+
this.shape(node, [scope, "::", name]);
|
|
168
|
+
if (scope.type != "namespace_identifier" || this.text(scope) != "std" ||
|
|
169
|
+
!["type_identifier", "identifier"].includes(name.type) || !["int64_t", "string"].includes(this.text(name)))
|
|
170
|
+
this.fail(node, "qualified scalar name");
|
|
171
|
+
return "std::" + this.text(name);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Converts a direct function call's exact argument list.
|
|
175
|
+
* @param {CstNode} node - Call node.
|
|
176
|
+
* @returns {{name: CstNode, arguments: CstNode[]}} Parsed call shape.
|
|
177
|
+
*/
|
|
178
|
+
call(node) {
|
|
179
|
+
if (node.type != "call_expression")
|
|
180
|
+
return this.fail(node, "direct call required");
|
|
181
|
+
const name = this.field(node, "function");
|
|
182
|
+
const list = this.field(node, "arguments");
|
|
183
|
+
this.shape(node, [name, list]);
|
|
184
|
+
if (!["identifier", "qualified_identifier"].includes(name.type) || list.type != "argument_list")
|
|
185
|
+
this.fail(node, "direct call shape");
|
|
186
|
+
const parts = this.parts(list);
|
|
187
|
+
const args = parts.slice(1, -1).filter((_part, index) => index % 2 == 0);
|
|
188
|
+
this.shape(list, ["(", ...args.flatMap((arg, index) => index == 0 ? [arg] : [",", arg]), ")"]);
|
|
189
|
+
return { arguments: args, name };
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Decodes a parser-backed ordinary CPP string token as UTF-8 bytes.
|
|
193
|
+
* @param {CstNode} node - String literal.
|
|
194
|
+
* @returns {string} Complete Unicode scalar value.
|
|
195
|
+
*/
|
|
196
|
+
string(node) {
|
|
197
|
+
if (node.type != "string_literal")
|
|
198
|
+
return this.fail(node, "ordinary string literal required");
|
|
199
|
+
const parts = this.parts(node);
|
|
200
|
+
if (parts[0]?.type != '"' || parts.at(-1)?.type != '"')
|
|
201
|
+
this.fail(node, "prefixed string literal");
|
|
202
|
+
const bytes = [];
|
|
203
|
+
for (let index = 1; index < parts.length - 1; index++) {
|
|
204
|
+
const child = parts[index];
|
|
205
|
+
const text = this.text(child);
|
|
206
|
+
if (child.type == "string_content") {
|
|
207
|
+
if (/[\r\n]/u.test(text))
|
|
208
|
+
this.fail(child, "raw line terminator in string literal");
|
|
209
|
+
for (const byte of new TextEncoder().encode(text))
|
|
210
|
+
bytes.push(byte);
|
|
211
|
+
}
|
|
212
|
+
else if (child.type == "escape_sequence") {
|
|
213
|
+
const simple = new Map([["a", 7], ["b", 8], ["f", 12], ["n", 10], ["r", 13], ["t", 9], ["v", 11], ["\\", 92], ['"', 34], ["'", 39], ["?", 63]]);
|
|
214
|
+
const value = text.slice(1);
|
|
215
|
+
if (text[0] != "\\")
|
|
216
|
+
this.fail(child, "invalid escape");
|
|
217
|
+
if (simple.has(value))
|
|
218
|
+
bytes.push(/** @type {number} */ (simple.get(value)));
|
|
219
|
+
else if (/^[0-7]{1,3}$/u.test(value) || /^x[0-9a-fA-F]+$/u.test(value)) {
|
|
220
|
+
const next = parts[index + 1];
|
|
221
|
+
// CPP consumes every adjacent hex digit; the frozen grammar caps each escape node at four.
|
|
222
|
+
if (value.startsWith("x") && next.type == "string_content" && next.startIndex == child.endIndex && /^[0-9a-fA-F]/u.test(this.text(next))) {
|
|
223
|
+
this.fail(child, "hexadecimal escape split by parser boundary");
|
|
224
|
+
}
|
|
225
|
+
const number = Number.parseInt(value[0] == "x" ? value.slice(1) : value, value[0] == "x" ? 16 : 8);
|
|
226
|
+
if (number > 255)
|
|
227
|
+
this.fail(child, "escape outside byte range");
|
|
228
|
+
bytes.push(number);
|
|
229
|
+
}
|
|
230
|
+
else
|
|
231
|
+
this.fail(child, "unsupported escape");
|
|
232
|
+
}
|
|
233
|
+
else
|
|
234
|
+
this.fail(child, "string child");
|
|
235
|
+
}
|
|
236
|
+
try {
|
|
237
|
+
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(new Uint8Array(bytes));
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
if (error instanceof TypeError)
|
|
241
|
+
return this.fail(node, "invalid UTF-8 literal bytes");
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Converts supported expressions without assuming CPP argument evaluation order.
|
|
247
|
+
* @param {CstNode} node - Expression node.
|
|
248
|
+
* @param {boolean} [nested] - Whether a semantic call would have unspecified order.
|
|
249
|
+
* @returns {Expression} Semantic expression.
|
|
250
|
+
*/
|
|
251
|
+
expression(node, nested = false) {
|
|
252
|
+
const location = this.location(node);
|
|
253
|
+
if (node.type == "condition_clause") {
|
|
254
|
+
const value = this.field(node, "value");
|
|
255
|
+
this.shape(node, ["(", value, ")"]);
|
|
256
|
+
return this.expression(value, nested);
|
|
257
|
+
}
|
|
258
|
+
if (node.type == "parenthesized_expression") {
|
|
259
|
+
const parts = this.parts(node);
|
|
260
|
+
this.shape(node, ["(", parts[1], ")"]);
|
|
261
|
+
return this.expression(parts[1], nested);
|
|
262
|
+
}
|
|
263
|
+
if (node.type == "identifier") {
|
|
264
|
+
const temporary = this.temporaryExpressions?.get(this.text(node));
|
|
265
|
+
if (temporary) {
|
|
266
|
+
this.temporaryExpressions?.delete(this.text(node));
|
|
267
|
+
return temporary;
|
|
268
|
+
}
|
|
269
|
+
return withParserRanges({ kind: "IdentifierExpression", location, name: this.identifier(node) }, { name: location });
|
|
270
|
+
}
|
|
271
|
+
if (node.type == "true" || node.type == "false") {
|
|
272
|
+
if (this.text(node) != node.type)
|
|
273
|
+
this.fail(node, "noncanonical Boolean literal spelling");
|
|
274
|
+
return withParserRanges({ kind: "BooleanLiteral", location, value: node.type == "true" }, { literal: location });
|
|
275
|
+
}
|
|
276
|
+
if (node.type == "number_literal")
|
|
277
|
+
this.fail(node, "integer literal requires exact std::int64_t construction");
|
|
278
|
+
if (node.type == "binary_expression") {
|
|
279
|
+
const left = this.field(node, "left");
|
|
280
|
+
const right = this.field(node, "right");
|
|
281
|
+
const operator = this.field(node, "operator");
|
|
282
|
+
const intent = binaryOperations.get(operator.type);
|
|
283
|
+
this.shape(node, [left, operator, right]);
|
|
284
|
+
if (!intent)
|
|
285
|
+
return this.fail(operator, "unsupported binary operator");
|
|
286
|
+
return this.binary(node, intent, this.expression(left, true), this.expression(right, true), operator);
|
|
287
|
+
}
|
|
288
|
+
if (node.type == "unary_expression") {
|
|
289
|
+
const operator = this.field(node, "operator");
|
|
290
|
+
const argument = this.field(node, "argument");
|
|
291
|
+
this.shape(node, [operator, argument]);
|
|
292
|
+
if (!["-", "!"].includes(operator.type))
|
|
293
|
+
this.fail(operator, "unsupported unary operator");
|
|
294
|
+
return this.unary(node, operator.type == "-" ? "Negate" : "Not", this.expression(argument, true), operator);
|
|
295
|
+
}
|
|
296
|
+
if (node.type == "call_expression") {
|
|
297
|
+
const call = this.call(node);
|
|
298
|
+
const name = this.text(call.name);
|
|
299
|
+
if (call.name.type == "qualified_identifier") {
|
|
300
|
+
const qualified = this.qualified(call.name);
|
|
301
|
+
if (qualified == "std::int64_t") {
|
|
302
|
+
if (call.arguments.length != 1 || call.arguments[0].type != "number_literal")
|
|
303
|
+
this.fail(node, "exact integer literal construction");
|
|
304
|
+
const spelling = this.text(call.arguments[0]);
|
|
305
|
+
if (!/^(?:0|[1-9][0-9]*)$/u.test(spelling) || !Number.isSafeInteger(Number(spelling)))
|
|
306
|
+
this.fail(call.arguments[0], "non-safe or noncanonical integer");
|
|
307
|
+
return withParserRanges({ kind: "IntegerLiteral", location, value: Number(spelling) }, { literal: location });
|
|
308
|
+
}
|
|
309
|
+
if (qualified == "std::string") {
|
|
310
|
+
if (call.arguments.length != 2 || call.arguments[1].type != "number_literal")
|
|
311
|
+
this.fail(node, "byte-counted string literal construction");
|
|
312
|
+
const value = this.string(call.arguments[0]);
|
|
313
|
+
const length = this.text(call.arguments[1]);
|
|
314
|
+
if (length != String(Buffer.byteLength(value, "utf8")))
|
|
315
|
+
this.fail(node, "string literal byte count");
|
|
316
|
+
return withParserRanges({ kind: "StringLiteral", location, value }, { literal: location });
|
|
317
|
+
}
|
|
318
|
+
this.fail(call.name, "qualified user call");
|
|
319
|
+
}
|
|
320
|
+
// Generated operations are separate temporary initializers; only exact scalar literal constructions may nest as calls.
|
|
321
|
+
if (nested)
|
|
322
|
+
this.fail(node, "caller call in unspecified-order expression");
|
|
323
|
+
if (name == "semantifold_integer_negate") {
|
|
324
|
+
if (call.arguments.length != 1)
|
|
325
|
+
this.fail(node, "negation helper arity");
|
|
326
|
+
return this.unary(node, "Negate", this.expression(call.arguments[0], true), call.name);
|
|
327
|
+
}
|
|
328
|
+
const intent = helpers.get(name);
|
|
329
|
+
if (intent) {
|
|
330
|
+
if (call.arguments.length != 2)
|
|
331
|
+
this.fail(node, "scalar helper arity");
|
|
332
|
+
return this.binary(node, intent, this.expression(call.arguments[0], true), this.expression(call.arguments[1], true), call.name);
|
|
333
|
+
}
|
|
334
|
+
if (call.arguments.length != 2)
|
|
335
|
+
this.fail(node, "semantic call arity");
|
|
336
|
+
const callee = this.identifier(call.name);
|
|
337
|
+
if (!this.generated && !this.declaredFunctions.has(callee))
|
|
338
|
+
this.fail(call.name, "implicit function declaration");
|
|
339
|
+
return withParserRanges({ kind: "CallExpression", location, callee,
|
|
340
|
+
arguments: call.arguments.map((argument) => this.expression(argument, true)) }, { callee: this.location(call.name) });
|
|
341
|
+
}
|
|
342
|
+
return this.fail(node);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Records parser intent before shared type resolution.
|
|
346
|
+
* @param {CstNode} node - Owning expression.
|
|
347
|
+
* @param {string} intent - Adapted operation.
|
|
348
|
+
* @param {Expression} left - Left operand.
|
|
349
|
+
* @param {Expression} right - Right operand.
|
|
350
|
+
* @param {CstNode} operator - Operator token.
|
|
351
|
+
* @returns {Expression} Pending binary expression.
|
|
352
|
+
*/
|
|
353
|
+
binary(node, intent, left, right, operator) {
|
|
354
|
+
return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "BinaryExpression", location: this.location(node), left, right }, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (intent)));
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Records parser intent for a unary operation.
|
|
358
|
+
* @param {CstNode} node - Owning expression.
|
|
359
|
+
* @param {"Negate" | "Not"} intent - Adapted operation.
|
|
360
|
+
* @param {Expression} operand - Operand.
|
|
361
|
+
* @param {CstNode} operator - Operator token.
|
|
362
|
+
* @returns {Expression} Pending unary expression.
|
|
363
|
+
*/
|
|
364
|
+
unary(node, intent, operand, operator) {
|
|
365
|
+
return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "UnaryExpression", location: this.location(node), operand }, { operator: this.location(operator) }), intent));
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Converts one initialized declaration or executable statement.
|
|
369
|
+
* @param {CstNode} node - Statement node.
|
|
370
|
+
* @returns {Statement} Semantic statement.
|
|
371
|
+
*/
|
|
372
|
+
statement(node) {
|
|
373
|
+
const location = this.location(node);
|
|
374
|
+
if (node.type == "declaration") {
|
|
375
|
+
const typeNode = node.children.find(({ field }) => field == "type")?.node;
|
|
376
|
+
if (!typeNode)
|
|
377
|
+
return missingType("cpp", "local", location);
|
|
378
|
+
const declarator = this.field(node, "declarator");
|
|
379
|
+
const parts = this.parts(node);
|
|
380
|
+
const immutable = parts[0].type == "type_qualifier";
|
|
381
|
+
this.shape(node, [...(immutable ? [parts[0]] : []), typeNode, declarator, ";"]);
|
|
382
|
+
if (immutable && this.text(parts[0]) != "const")
|
|
383
|
+
this.fail(parts[0], "local qualifier");
|
|
384
|
+
if (declarator.type != "init_declarator")
|
|
385
|
+
this.fail(declarator, "initialized simple local required");
|
|
386
|
+
const name = this.field(declarator, "declarator");
|
|
387
|
+
const value = this.field(declarator, "value");
|
|
388
|
+
this.shape(declarator, [name, "=", value]);
|
|
389
|
+
return withParserRanges({ kind: "LocalDeclaration", location, name: this.identifier(name), type: this.type(typeNode), mutable: !immutable,
|
|
390
|
+
initializer: this.expression(value) }, { name: this.location(name), operator: this.location(this.parts(declarator)[1]) });
|
|
391
|
+
}
|
|
392
|
+
if (node.type == "return_statement") {
|
|
393
|
+
const parts = this.parts(node);
|
|
394
|
+
this.shape(node, ["return", parts[1], ";"]);
|
|
395
|
+
return { kind: "ReturnStatement", location, expression: this.expression(parts[1]) };
|
|
396
|
+
}
|
|
397
|
+
if (node.type == "if_statement") {
|
|
398
|
+
const condition = this.field(node, "condition");
|
|
399
|
+
const consequence = this.field(node, "consequence");
|
|
400
|
+
const alternative = node.children.find(({ field }) => field == "alternative")?.node;
|
|
401
|
+
this.shape(node, ["if", condition, consequence, ...(alternative ? [alternative] : [])]);
|
|
402
|
+
const statement = { kind: /** @type {const} */ ("IfStatement"), location, condition: this.expression(condition), consequent: this.block(consequence) };
|
|
403
|
+
if (!alternative)
|
|
404
|
+
return statement;
|
|
405
|
+
const branch = this.parts(alternative)[1];
|
|
406
|
+
this.shape(alternative, ["else", branch]);
|
|
407
|
+
return { ...statement, alternate: branch.type == "if_statement"
|
|
408
|
+
? { kind: "Block", location: this.location(branch), statements: [this.statement(branch)] } : this.block(branch) };
|
|
409
|
+
}
|
|
410
|
+
if (node.type == "expression_statement") {
|
|
411
|
+
const expression = this.parts(node)[0];
|
|
412
|
+
this.shape(node, [expression, ";"]);
|
|
413
|
+
if (expression.type == "assignment_expression") {
|
|
414
|
+
const left = this.field(expression, "left");
|
|
415
|
+
const right = this.field(expression, "right");
|
|
416
|
+
const operator = this.field(expression, "operator");
|
|
417
|
+
this.shape(expression, [left, "=", right]);
|
|
418
|
+
const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), name: this.identifier(left), location: this.location(left) }, { name: this.location(left) });
|
|
419
|
+
return withParserRanges({ kind: "AssignmentStatement", location, target, expression: this.expression(right) }, { operator: this.location(operator) });
|
|
420
|
+
}
|
|
421
|
+
const call = this.call(expression);
|
|
422
|
+
if (!/^semantifold_print_(?:integer|boolean|string)$/u.test(this.text(call.name)) || call.arguments.length != 1)
|
|
423
|
+
this.fail(node, "print scaffold");
|
|
424
|
+
const value = this.expression(call.arguments[0]);
|
|
425
|
+
const statement = { kind: /** @type {const} */ ("PrintStatement"), location, expression: value };
|
|
426
|
+
this.printTypes.set(statement, { node: call.name, type: this.text(call.name).slice("semantifold_print_".length) });
|
|
427
|
+
return statement;
|
|
428
|
+
}
|
|
429
|
+
return this.fail(node);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Converts one lexical braced block in source order.
|
|
433
|
+
* @param {CstNode} node - Block node.
|
|
434
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
435
|
+
*/
|
|
436
|
+
block(node) {
|
|
437
|
+
if (node.type != "compound_statement")
|
|
438
|
+
this.fail(node, "braced block required");
|
|
439
|
+
const parts = this.parts(node);
|
|
440
|
+
this.shape(node, ["{", ...parts.slice(1, -1), "}"]);
|
|
441
|
+
return { kind: "Block", location: this.location(node), statements: this.generated
|
|
442
|
+
? this.generatedStatements(node.children.map(({ node: child }) => child).slice(1, -1))
|
|
443
|
+
: parts.slice(1, -1).map((child) => this.statement(child)) };
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Converts one namespace-scope semantic function.
|
|
447
|
+
* @param {CstNode} node - Function definition.
|
|
448
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
449
|
+
*/
|
|
450
|
+
function(node) {
|
|
451
|
+
const type = this.field(node, "type");
|
|
452
|
+
const declarator = this.field(node, "declarator");
|
|
453
|
+
const body = this.field(node, "body");
|
|
454
|
+
this.shape(node, [type, declarator, body]);
|
|
455
|
+
if (declarator.type != "function_declarator")
|
|
456
|
+
this.fail(node, "namespace-scope function required");
|
|
457
|
+
const name = this.field(declarator, "declarator");
|
|
458
|
+
const parameters = this.field(declarator, "parameters");
|
|
459
|
+
this.shape(declarator, [name, parameters]);
|
|
460
|
+
const parts = this.parts(parameters);
|
|
461
|
+
this.shape(parameters, ["(", "parameter_declaration", ",", "parameter_declaration", ")"]);
|
|
462
|
+
const converted = [parts[1], parts[3]].map((parameter) => {
|
|
463
|
+
const typeNode = this.field(parameter, "type");
|
|
464
|
+
const nameNode = this.field(parameter, "declarator");
|
|
465
|
+
this.shape(parameter, [typeNode, nameNode]);
|
|
466
|
+
return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: this.location(parameter), name: this.identifier(nameNode), type: this.type(typeNode) }, { name: this.location(nameNode) });
|
|
467
|
+
});
|
|
468
|
+
this.declaredFunctions.add(this.identifier(name));
|
|
469
|
+
return withParserRanges({ kind: "FunctionDeclaration", location: this.location(node), name: this.identifier(name), parameters: converted,
|
|
470
|
+
returnType: this.type(type), body: this.block(body) }, { name: this.location(name) });
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Removes only the exact parameterless main and zero-status scaffolding.
|
|
474
|
+
* @param {CstNode} node - Entry definition.
|
|
475
|
+
* @returns {import("../semantic/types.js").EntryPoint} Semantic entry.
|
|
476
|
+
*/
|
|
477
|
+
main(node) {
|
|
478
|
+
const type = this.field(node, "type");
|
|
479
|
+
const declarator = this.field(node, "declarator");
|
|
480
|
+
const body = this.field(node, "body");
|
|
481
|
+
this.shape(node, [type, declarator, body]);
|
|
482
|
+
const name = this.field(declarator, "declarator");
|
|
483
|
+
const parameters = this.field(declarator, "parameters");
|
|
484
|
+
this.shape(declarator, [name, parameters]);
|
|
485
|
+
if (this.text(type) != "int" || this.text(name) != "main")
|
|
486
|
+
this.fail(node, "main signature");
|
|
487
|
+
this.shape(parameters, ["(", ")"]);
|
|
488
|
+
if (body.type != "compound_statement")
|
|
489
|
+
this.fail(body, "braced main required");
|
|
490
|
+
const parts = this.parts(body);
|
|
491
|
+
const status = parts.at(-2);
|
|
492
|
+
if (!status)
|
|
493
|
+
this.fail(body, "main status");
|
|
494
|
+
this.shape(body, ["{", ...parts.slice(1, -1), "}"]);
|
|
495
|
+
this.shape(status, ["return", "number_literal", ";"]);
|
|
496
|
+
if (this.text(this.parts(status)[1]) != "0")
|
|
497
|
+
this.fail(status, "entry status");
|
|
498
|
+
return { kind: "EntryPoint", location: this.location(node), body: { kind: "Block", location: this.location(body),
|
|
499
|
+
statements: this.generated ? this.generatedStatements(body.children.map(({ node: child }) => child).filter((child) => child.startIndex > body.startIndex && child.endIndex <= status.startIndex))
|
|
500
|
+
: parts.slice(1, -2).map((child) => this.statement(child)) } };
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Converts one complete translation unit after exhaustive recovery rejection.
|
|
504
|
+
* @param {CstNode} root - Frozen translation unit.
|
|
505
|
+
* @returns {import("../semantic/types.js").SemanticModule} Validated semantic module.
|
|
506
|
+
*/
|
|
507
|
+
module(root) {
|
|
508
|
+
this.validateTree(root);
|
|
509
|
+
this.generated = root.children.some(({ node }) => node.type == "comment" && this.text(node) == "/* semantifold:program:cpp:v1 */");
|
|
510
|
+
if (root.type != "translation_unit")
|
|
511
|
+
this.fail(root, "translation unit required");
|
|
512
|
+
const runtime = new CppReader(this.filename, cppRuntime);
|
|
513
|
+
const expected = runtime.significant(parseCppCst(cppRuntime).root);
|
|
514
|
+
const actual = this.significant(root).filter((node) => !(node.type == "comment" && this.text(node) == "/* semantifold:program:cpp:v1 */"));
|
|
515
|
+
if (actual.length < expected.length)
|
|
516
|
+
this.fail(root, "complete CPP runtime required");
|
|
517
|
+
expected.forEach((node, index) => this.compareTree(actual[index], node, runtime));
|
|
518
|
+
const remaining = actual.slice(expected.length);
|
|
519
|
+
if (!this.generated)
|
|
520
|
+
for (const node of remaining)
|
|
521
|
+
this.rejectScaffoldComments(node);
|
|
522
|
+
const definitions = remaining.filter((node) => node.type != "comment" && (!this.generated || node.type != "declaration"));
|
|
523
|
+
if (definitions.some((node) => node.type != "function_definition"))
|
|
524
|
+
this.fail(root, "translation unit members");
|
|
525
|
+
if (definitions.length < 2)
|
|
526
|
+
this.fail(root, "semantic function and main required");
|
|
527
|
+
const module = { kind: /** @type {const} */ ("Module"), location: this.location(root), functions: definitions.slice(0, -1).map((node) => this.function(node)),
|
|
528
|
+
entryPoint: this.main(definitions[definitions.length - 1]) };
|
|
529
|
+
if (this.generated)
|
|
530
|
+
validateNativeGraph(module, "cpp");
|
|
531
|
+
const validated = validateParsedModule(module, "cpp");
|
|
532
|
+
this.validatePrintTypes(validated);
|
|
533
|
+
if (this.generated) {
|
|
534
|
+
validateBackendModule(validated, "cpp");
|
|
535
|
+
const canonical = generateCpp(validated);
|
|
536
|
+
if (typeof canonical != "string")
|
|
537
|
+
throw new Error("CPP backend returned a nontext entry artifact.");
|
|
538
|
+
this.compareTree(root, parseCppCst(canonical).root, new CppReader(this.filename, canonical));
|
|
539
|
+
}
|
|
540
|
+
return validated;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Checks native print helper selection after semantic scalar resolution.
|
|
544
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Resolved module.
|
|
545
|
+
* @returns {void}
|
|
546
|
+
*/
|
|
547
|
+
validatePrintTypes(module) {
|
|
548
|
+
const planner = new OrderedExpressionPlanner(module, "cpp");
|
|
549
|
+
/**
|
|
550
|
+
* Checks one lexical block with its visible scalar bindings.
|
|
551
|
+
* @param {import("../semantic/types.js").Block} block - Semantic block.
|
|
552
|
+
* @param {Map<string, import("../semantic/types.js").SemanticTypeName>} inherited - Visible bindings.
|
|
553
|
+
* @returns {void}
|
|
554
|
+
*/
|
|
555
|
+
const visit = (block, inherited) => {
|
|
556
|
+
const bindings = new Map(inherited);
|
|
557
|
+
for (const statement of block.statements) {
|
|
558
|
+
if (statement.kind == "LocalDeclaration")
|
|
559
|
+
bindings.set(statement.name, statement.type.name);
|
|
560
|
+
if (statement.kind == "PrintStatement") {
|
|
561
|
+
const expected = this.printTypes.get(statement);
|
|
562
|
+
if (!expected)
|
|
563
|
+
throw new Error("CPP print statement lost its parser helper identity.");
|
|
564
|
+
if (planner.type(statement.expression, bindings) != expected.type)
|
|
565
|
+
this.fail(expected.node, "print helper scalar mismatch");
|
|
566
|
+
}
|
|
567
|
+
if (statement.kind == "IfStatement") {
|
|
568
|
+
visit(statement.consequent, bindings);
|
|
569
|
+
if (statement.alternate)
|
|
570
|
+
visit(statement.alternate, bindings);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
for (const declaration of module.functions)
|
|
575
|
+
visit(declaration.body, new Map(declaration.parameters.map((parameter) => [parameter.name, parameter.type.name])));
|
|
576
|
+
visit(module.entryPoint.body, new Map());
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Rejects profile-looking comments outside a complete canonical generated program.
|
|
580
|
+
* @param {CstNode} node - Current node.
|
|
581
|
+
* @returns {void}
|
|
582
|
+
*/
|
|
583
|
+
rejectScaffoldComments(node) {
|
|
584
|
+
if (node.type == "comment" && /semantifold:|@semantifold/u.test(this.text(node)))
|
|
585
|
+
this.fail(node, "unrecognized scaffold comment");
|
|
586
|
+
for (const { node: child } of node.children)
|
|
587
|
+
this.rejectScaffoldComments(child);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Retains every scaffold comment and structural edge, ignoring only ordinary comments.
|
|
591
|
+
* @param {CstNode} node - CST parent.
|
|
592
|
+
* @returns {CstNode[]} Complete significant child list.
|
|
593
|
+
*/
|
|
594
|
+
significant(node) {
|
|
595
|
+
return node.children.map(({ node: child }) => child).filter((child) => child.type != "comment" || /semantifold:|@semantifold/u.test(this.text(child)));
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Verifies every token, field, type, use, ordering edge and consumer against the canonical plan.
|
|
599
|
+
* This checks the original CST; it never recovers meaning from generated source text.
|
|
600
|
+
* @param {CstNode} actual - Original tree node.
|
|
601
|
+
* @param {CstNode} expected - Canonical tree node for the reconstructed semantics.
|
|
602
|
+
* @param {CppReader} canonical - Canonical token reader.
|
|
603
|
+
* @returns {void}
|
|
604
|
+
*/
|
|
605
|
+
compareTree(actual, expected, canonical) {
|
|
606
|
+
if (actual.type != expected.type || actual.named != expected.named || actual.extra != expected.extra)
|
|
607
|
+
this.fail(actual, "generated scaffold node shape");
|
|
608
|
+
const left = this.significant(actual);
|
|
609
|
+
const right = canonical.significant(expected);
|
|
610
|
+
if (left.length != right.length)
|
|
611
|
+
this.fail(actual, "generated scaffold child count");
|
|
612
|
+
if (!left.length && this.text(actual) != canonical.text(expected))
|
|
613
|
+
this.fail(actual, "generated scaffold token, type, order or consumer");
|
|
614
|
+
left.forEach((child, index) => {
|
|
615
|
+
if (actual.children.find((edge) => edge.node === child)?.field != expected.children.find((edge) => edge.node === right[index])?.field)
|
|
616
|
+
this.fail(child, "generated scaffold field");
|
|
617
|
+
this.compareTree(child, right[index], canonical);
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Recognizes the shape of an inert generated unused-binding cast; canonical comparison checks its exact target and placement.
|
|
622
|
+
* @param {CstNode} node - Candidate statement.
|
|
623
|
+
* @returns {boolean} Whether this is a discard-shaped candidate.
|
|
624
|
+
*/
|
|
625
|
+
discard(node) {
|
|
626
|
+
return node.type == "expression_statement" && this.parts(node)[0]?.type == "cast_expression";
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Reconstructs paired statement regions before mandatory whole-CST canonical verification.
|
|
630
|
+
* @param {CstNode[]} children - Ordered block children without braces or main cleanup.
|
|
631
|
+
* @returns {Statement[]} Candidate semantic statements.
|
|
632
|
+
*/
|
|
633
|
+
generatedStatements(children) {
|
|
634
|
+
const nodes = children.filter((node) => node.type != "comment" || /semantifold:|@semantifold/u.test(this.text(node)));
|
|
635
|
+
/** @type {Statement[]} */
|
|
636
|
+
const statements = [];
|
|
637
|
+
let cursor = 0;
|
|
638
|
+
while (cursor < nodes.length && this.discard(nodes[cursor]))
|
|
639
|
+
cursor++;
|
|
640
|
+
while (cursor < nodes.length) {
|
|
641
|
+
const begin = nodes[cursor++];
|
|
642
|
+
const match = begin.type == "comment" && /^\/\* semantifold:ordered-expression:cpp:v1 begin ([0-9]{6}) ([0-9a-f]{64}) \*\/$/u.exec(this.text(begin));
|
|
643
|
+
if (!match)
|
|
644
|
+
this.fail(begin, "complete ordered statement region required");
|
|
645
|
+
const outer = this.temporaryExpressions;
|
|
646
|
+
const outerNames = this.temporaryNames;
|
|
647
|
+
this.temporaryExpressions = new Map();
|
|
648
|
+
this.temporaryNames = new Set();
|
|
649
|
+
while (cursor < nodes.length && this.temporaryDeclaration(nodes[cursor]))
|
|
650
|
+
cursor = this.readTemporary(nodes, cursor);
|
|
651
|
+
const consumer = nodes[cursor++];
|
|
652
|
+
if (!consumer)
|
|
653
|
+
this.fail(begin, "missing ordered consumer");
|
|
654
|
+
const statement = this.statement(consumer);
|
|
655
|
+
if (this.temporaryExpressions.size != 0)
|
|
656
|
+
this.fail(consumer, "unconsumed ordered temporary");
|
|
657
|
+
if (statement.kind == "LocalDeclaration" && nodes[cursor] && this.discard(nodes[cursor]))
|
|
658
|
+
cursor++;
|
|
659
|
+
const end = nodes[cursor++];
|
|
660
|
+
if (!end || end.type != "comment" || this.text(end) != `/* semantifold:ordered-expression:cpp:v1 end ${match[1]} ${match[2]} */`)
|
|
661
|
+
this.fail(end ?? begin, "ordered marker pair");
|
|
662
|
+
this.temporaryExpressions = outer;
|
|
663
|
+
this.temporaryNames = outerNames;
|
|
664
|
+
statements.push(statement);
|
|
665
|
+
}
|
|
666
|
+
return statements;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Identifies only a declaration at the current region level, without descendant searching.
|
|
670
|
+
* @param {CstNode} node - Candidate node.
|
|
671
|
+
* @returns {boolean} Whether the direct initialized name uses the reserved prefix.
|
|
672
|
+
*/
|
|
673
|
+
temporaryDeclaration(node) {
|
|
674
|
+
if (node.type != "declaration")
|
|
675
|
+
return false;
|
|
676
|
+
const declarator = node.children.find(({ field }) => field == "declarator")?.node;
|
|
677
|
+
const name = declarator?.children.find(({ field }) => field == "declarator")?.node;
|
|
678
|
+
return name?.type == "identifier" && this.text(name).startsWith("semantifold_ordered_");
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Expands one candidate temporary, including its conditional RHS, retaining original operation tokens.
|
|
682
|
+
* @param {CstNode[]} nodes - Current lexical sequence.
|
|
683
|
+
* @param {number} cursor - Declaration position.
|
|
684
|
+
* @returns {number} Next unconsumed position.
|
|
685
|
+
*/
|
|
686
|
+
readTemporary(nodes, cursor) {
|
|
687
|
+
const node = nodes[cursor++];
|
|
688
|
+
const declarator = this.field(node, "declarator");
|
|
689
|
+
const nameNode = this.field(declarator, "declarator");
|
|
690
|
+
const name = this.text(nameNode);
|
|
691
|
+
const type = this.field(node, "type");
|
|
692
|
+
const value = this.field(declarator, "value");
|
|
693
|
+
this.shape(node, [type, declarator, ";"]);
|
|
694
|
+
this.shape(declarator, [nameNode, "=", value]);
|
|
695
|
+
this.type(type);
|
|
696
|
+
if (!/^semantifold_ordered_[0-9]{6}$/u.test(name) || this.temporaryNames?.has(name))
|
|
697
|
+
this.fail(nameNode, "ordered temporary declaration");
|
|
698
|
+
this.temporaryNames?.add(name);
|
|
699
|
+
let expression = this.expression(value);
|
|
700
|
+
const branch = nodes[cursor];
|
|
701
|
+
if (branch?.type == "if_statement" && ["identifier", "true", "false"].includes(value.type)) {
|
|
702
|
+
const condition = this.field(branch, "condition");
|
|
703
|
+
const body = this.field(branch, "consequence");
|
|
704
|
+
this.shape(branch, ["if", condition, body]);
|
|
705
|
+
this.shape(condition, ["(", this.parts(condition)[1], ")"]);
|
|
706
|
+
const test = this.parts(condition)[1];
|
|
707
|
+
const isOr = test.type == "unary_expression";
|
|
708
|
+
const target = isOr ? this.field(test, "argument") : test;
|
|
709
|
+
if (target.type != "identifier" || this.text(target) != name)
|
|
710
|
+
this.fail(target, "short-circuit temporary test");
|
|
711
|
+
if (isOr)
|
|
712
|
+
this.shape(test, ["!", target]);
|
|
713
|
+
if (body.type != "compound_statement")
|
|
714
|
+
this.fail(body, "short-circuit block");
|
|
715
|
+
const inside = this.significant(body).slice(1, -1);
|
|
716
|
+
let offset = 0;
|
|
717
|
+
while (offset < inside.length && this.temporaryDeclaration(inside[offset]))
|
|
718
|
+
offset = this.readTemporary(inside, offset);
|
|
719
|
+
if (offset != inside.length - 1)
|
|
720
|
+
this.fail(body, "short-circuit final write");
|
|
721
|
+
const assignment = inside[offset];
|
|
722
|
+
this.shape(assignment, ["assignment_expression", ";"]);
|
|
723
|
+
const assigned = this.parts(assignment)[0];
|
|
724
|
+
const left = this.field(assigned, "left");
|
|
725
|
+
const right = this.field(assigned, "right");
|
|
726
|
+
this.shape(assigned, [left, "=", right]);
|
|
727
|
+
if (left.type != "identifier" || this.text(left) != name)
|
|
728
|
+
this.fail(left, "short-circuit result write");
|
|
729
|
+
this.shape(right, ["(", "binary_expression", ")"]);
|
|
730
|
+
const binary = this.parts(right)[1];
|
|
731
|
+
const repeated = this.field(binary, "left");
|
|
732
|
+
const operand = this.field(binary, "right");
|
|
733
|
+
const operator = this.field(binary, "operator");
|
|
734
|
+
this.shape(binary, [repeated, isOr ? "||" : "&&", operand]);
|
|
735
|
+
if (repeated.type != "identifier" || this.text(repeated) != name)
|
|
736
|
+
this.fail(repeated, "short-circuit consumed value");
|
|
737
|
+
expression = this.binary(node, isOr ? "Or" : "And", expression, this.expression(operand), operator);
|
|
738
|
+
cursor++;
|
|
739
|
+
}
|
|
740
|
+
this.temporaryExpressions?.set(name, expression);
|
|
741
|
+
return cursor;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Parses only the frozen legacy CST, with no source-text recovery path.
|
|
746
|
+
* @param {{filename: string, source: string}} input - Exact caller source.
|
|
747
|
+
* @returns {import("../semantic/types.js").SemanticModule} Parsed C++ semantics.
|
|
748
|
+
*/
|
|
749
|
+
export function parseCpp({ filename, source }) {
|
|
750
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
751
|
+
const coordinates = createCoordinateIndex(source);
|
|
752
|
+
const offset = source.search(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u);
|
|
753
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "cpp", message: "CPP source contains a lone UTF-16 surrogate.",
|
|
754
|
+
location: { filename, start: indexedPointAt(coordinates, offset), end: indexedPointAt(coordinates, offset + 1) } });
|
|
755
|
+
}
|
|
756
|
+
if (source.length > maximumCppSourceLength) {
|
|
757
|
+
const coordinates = createCoordinateIndex(source);
|
|
758
|
+
return unsupportedSyntax("cpp", "source exceeds the frozen CPP parser's 32767 UTF-16 input limit", {
|
|
759
|
+
filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length)
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
let snapshot;
|
|
763
|
+
try {
|
|
764
|
+
snapshot = parseCppCst(source);
|
|
765
|
+
}
|
|
766
|
+
catch (error) {
|
|
767
|
+
const coordinates = createCoordinateIndex(source);
|
|
768
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "cpp",
|
|
769
|
+
cause: error instanceof Error ? error : undefined, message: "The qualified CPP parser could not produce a complete CST.",
|
|
770
|
+
location: { filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length) } });
|
|
771
|
+
}
|
|
772
|
+
const reader = new CppReader(filename, source);
|
|
773
|
+
try {
|
|
774
|
+
return reader.module(snapshot.root);
|
|
775
|
+
}
|
|
776
|
+
catch (error) {
|
|
777
|
+
if (reader.generated && error instanceof SemantifoldDiagnostic && error.language == "cpp" &&
|
|
778
|
+
error.code != "PARSE_ERROR" && error.code != "UNSUPPORTED_SYNTAX") {
|
|
779
|
+
return unsupportedSyntax("cpp", `invalid generated ordered scaffold: ${error.code}`, error.location ?? reader.location(snapshot.root));
|
|
780
|
+
}
|
|
781
|
+
throw error;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3BwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9jcHAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQTtBQUM5QyxPQUFPLEVBQUMsd0JBQXdCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQTtBQUMzRSxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQTtBQUNwRSxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxrQ0FBa0MsQ0FBQTtBQUNwRSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDckQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sdUJBQXVCLENBQUE7QUFDM0QsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLDRCQUE0QixDQUFBO0FBQzFELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQTtBQUMzQyxPQUFPLEVBQUMsV0FBVyxFQUFFLHFCQUFxQixFQUFFLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDdEYsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzdFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDBCQUEwQixDQUFBO0FBQzdELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDJCQUEyQixDQUFBO0FBQzFELE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBQzVELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzVELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUU3QywyREFBMkQ7QUFDM0Qsc0VBQXNFO0FBQ3RFLG9FQUFvRTtBQUVwRSxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQy9CLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQztJQUN2RixDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLG9CQUFvQixDQUFDO0lBQ2hHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQztDQUM1QixDQUFDLENBQUE7QUFDRixNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUN0QixDQUFDLHlCQUF5QixFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUMsOEJBQThCLEVBQUUsVUFBVSxDQUFDO0lBQ25GLENBQUMsOEJBQThCLEVBQUUsVUFBVSxDQUFDLEVBQUUsQ0FBQywyQkFBMkIsRUFBRSxjQUFjLENBQUM7SUFDM0YsQ0FBQywwQkFBMEIsRUFBRSxhQUFhLENBQUMsRUFBRSxDQUFDLDhCQUE4QixFQUFFLGdCQUFnQixDQUFDO0NBQ2hHLENBQUMsQ0FBQTtBQUVGLHNFQUFzRTtBQUN0RSxNQUFNLE9BQU8sU0FBUztJQUNwQjs7OztPQUlHO0lBQ0gsWUFBWSxRQUFRLEVBQUUsTUFBTTtRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsV0FBVyxHQUFHLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ2hELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFBO1FBQ3RCLGtEQUFrRDtRQUNsRCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsU0FBUyxDQUFBO1FBQ3JDLHNDQUFzQztRQUN0QyxJQUFJLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQTtRQUMvQiw0REFBNEQ7UUFDNUQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQzNCLDBCQUEwQjtRQUMxQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUNwQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFFBQVEsQ0FBQyxJQUFJO1FBQ1gsT0FBTyxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBQyxDQUFBO0lBQ2xKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBSSxDQUFDLElBQUk7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQzFELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJO1FBQzNCLGlCQUFpQixDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQ3ZELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUM7UUFDMUIsSUFBSSxLQUFLLEdBQUcsR0FBRztZQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLCtDQUErQyxDQUFDLENBQUE7UUFDakYsS0FBSyxNQUFNLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxJQUFJLElBQUksQ0FBQyxRQUFRO1lBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQzlFLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNoRCxNQUFNLElBQUkscUJBQXFCLENBQUMsRUFBQyxJQUFJLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLDJCQUEyQixJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1FBQzNKLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxTQUFTO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsK0JBQStCLENBQUMsQ0FBQTtRQUMxRixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxTQUFTLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMxRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSx3QkFBd0IsQ0FBQyxDQUFBO1FBQzNDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksU0FBUyxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUU1Qiw2RkFBNkY7WUFDN0YsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3RGLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxDQUFDLENBQUE7WUFDcEQsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxJQUFJO1FBQ1IsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDLENBQUE7SUFDL0YsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJO1FBQ2QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFDLEtBQUssRUFBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUE7UUFFaEUsSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGlCQUFpQixJQUFJLFNBQVMsQ0FBQyxDQUFBO1FBQy9FLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUN4QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVE7UUFDbEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUVqQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQ3ZFLE9BQU8sUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLGNBQWMsQ0FBQyxDQUFBO0lBQ2hKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsVUFBVSxDQUFDLElBQUk7UUFDYixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRTVCLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxZQUFZLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsb0NBQW9DLENBQUMsQ0FBQTtRQUM5RyxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBSSxDQUFDLElBQUk7UUFDUCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxJQUFJLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRTdGLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxzQkFBc0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksZ0JBQWdCLElBQUksUUFBUSxJQUFJLE1BQU0sQ0FBQztZQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLG1CQUFtQixDQUFDLENBQUE7UUFDdEksTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7UUFFbkUsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLHlCQUF5QixDQUFDLENBQUE7UUFDNUQsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFNBQVMsQ0FBQyxJQUFJO1FBQ1osTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFFckMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7UUFDckMsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLHNCQUFzQixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSztZQUNuRSxDQUFDLENBQUMsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLENBQUMsQ0FBQTtRQUN0SixPQUFPLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2xDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBSSxDQUFDLElBQUk7UUFDUCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksaUJBQWlCO1lBQUUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxzQkFBc0IsQ0FBQyxDQUFBO1FBQ2xGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFBO1FBQ3pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFBO1FBRTFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7UUFDOUIsSUFBSSxDQUFDLENBQUMsWUFBWSxFQUFFLHNCQUFzQixDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLGVBQWU7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxtQkFBbUIsQ0FBQyxDQUFBO1FBQ3JJLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBRXhFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUM5RixPQUFPLEVBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQTtJQUNoQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxJQUFJO1FBQ1QsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLGdCQUFnQjtZQUFFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsa0NBQWtDLENBQUMsQ0FBQTtRQUM3RixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRTlCLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxHQUFHLElBQUksS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxHQUFHO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUseUJBQXlCLENBQUMsQ0FBQTtRQUNsRyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUE7UUFFaEIsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUM7WUFDdEQsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQzFCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7WUFFN0IsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ25DLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7b0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsdUNBQXVDLENBQUMsQ0FBQTtnQkFDbkYsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7b0JBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUNyRSxDQUFDO2lCQUNJLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxpQkFBaUIsRUFBRSxDQUFDO2dCQUN6QyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtnQkFDL0ksTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtnQkFFM0IsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSTtvQkFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO2dCQUN2RCxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO29CQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtxQkFDdkUsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUN2RSxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFBO29CQUU3QiwyRkFBMkY7b0JBQzNGLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLGdCQUFnQixJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO3dCQUN6SSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSw2Q0FBNkMsQ0FBQyxDQUFBO29CQUNqRSxDQUFDO29CQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7b0JBRWxHLElBQUksTUFBTSxHQUFHLEdBQUc7d0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsMkJBQTJCLENBQUMsQ0FBQTtvQkFDL0QsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFDcEIsQ0FBQzs7b0JBQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsb0JBQW9CLENBQUMsQ0FBQTtZQUMvQyxDQUFDOztnQkFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxjQUFjLENBQUMsQ0FBQTtRQUN6QyxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0gsT0FBTyxJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQy9GLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxLQUFLLFlBQVksU0FBUztnQkFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLDZCQUE2QixDQUFDLENBQUE7WUFDckYsTUFBTSxLQUFLLENBQUE7UUFDYixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUFDLElBQUksRUFBRSxNQUFNLEdBQUcsS0FBSztRQUM3QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRXBDLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBRXZDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQ25DLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDdkMsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSwwQkFBMEIsRUFBRSxDQUFDO1lBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7WUFFOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUE7WUFDdEMsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUMxQyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQzlCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1lBRWpFLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsSUFBSSxDQUFDLG9CQUFvQixFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7Z0JBQ2xELE9BQU8sU0FBUyxDQUFBO1lBQ2xCLENBQUM7WUFDRCxPQUFPLGdCQUFnQixDQUFDLEVBQUMsSUFBSSxFQUFFLHNCQUFzQixFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7UUFDbEgsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxNQUFNLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNoRCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUk7Z0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsdUNBQXVDLENBQUMsQ0FBQTtZQUMxRixPQUFPLGdCQUFnQixDQUFDLEVBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxNQUFNLEVBQUMsRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO1FBQzlHLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksZ0JBQWdCO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMERBQTBELENBQUMsQ0FBQTtRQUM5RyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksbUJBQW1CLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQTtZQUNyQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQTtZQUN2QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQTtZQUM3QyxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBRWxELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO1lBQ3pDLElBQUksQ0FBQyxNQUFNO2dCQUFFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsNkJBQTZCLENBQUMsQ0FBQTtZQUN0RSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUN2RyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLGtCQUFrQixFQUFFLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUE7WUFDN0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUE7WUFFN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQTtZQUN0QyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7Z0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtZQUMxRixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUM3RyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLGlCQUFpQixFQUFFLENBQUM7WUFDbkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUM1QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUVqQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFB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RSxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUMxQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQTtRQUNqRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQTtRQUV2RCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFBO1FBQzFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxNQUFNO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQTtRQUM1RixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ2xDLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxvQkFBb0I7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxzQkFBc0IsQ0FBQyxDQUFBO1FBQzlFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRTNCLElBQUksQ0FBQyxNQUFNO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUE7UUFDM0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDbkQsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUNyRCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUc7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQTtRQUM5RSxPQUFPLEVBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztnQkFDNUcsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNqSCxLQUFLLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQzNFLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFDLEVBQUMsQ0FBQTtJQUNsRSxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxJQUFJO1FBQ1QsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxTQUFTLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxrQ0FBa0MsQ0FBQyxDQUFBO1FBQ2hJLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxrQkFBa0I7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSwyQkFBMkIsQ0FBQyxDQUFBO1FBQ2pGLE1BQU0sT0FBTyxHQUFHLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUE7UUFDeEQsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDbEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGtDQUFrQyxDQUFDLENBQUMsQ0FBQTtRQUUxSSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU07WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSwrQkFBK0IsQ0FBQyxDQUFBO1FBQ3JGLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQTtRQUNqRixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUUvQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVM7WUFBRSxLQUFLLE1BQU0sSUFBSSxJQUFJLFNBQVM7Z0JBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3BGLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksU0FBUyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQTtRQUV6SCxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUkscUJBQXFCLENBQUM7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSwwQkFBMEIsQ0FBQyxDQUFBO1FBQy9HLElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUscUNBQXFDLENBQUMsQ0FBQTtRQUNsRixNQUFNLE1BQU0sR0FBRyxFQUFDLElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsRUFBRSxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxSixVQUFVLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUE7UUFFN0QsSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUN0RCxNQUFNLFNBQVMsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFFckQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQ2xDLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLHFCQUFxQixDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQTtZQUN2QyxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUE7WUFFeEMsSUFBSSxPQUFPLFNBQVMsSUFBSSxRQUFRO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQTtZQUNuRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQTtRQUM5RixDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxrQkFBa0IsQ0FBQyxNQUFNO1FBQ3ZCLE1BQU0sT0FBTyxHQUFHLElBQUksd0JBQXdCLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFBO1FBQzNEOzs7OztXQUtHO1FBQ0gsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUU7WUFDakMsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUE7WUFFbkMsS0FBSyxNQUFNLFNBQVMsSUFBSSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3pDLElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxrQkFBa0I7b0JBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQzNGLElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO29CQUN2QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtvQkFFL0MsSUFBSSxDQUFDLFFBQVE7d0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFBO29CQUN0RixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsSUFBSSxRQUFRLENBQUMsSUFBSTt3QkFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsOEJBQThCLENBQUMsQ0FBQTtnQkFDN0gsQ0FBQztnQkFDRCxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksYUFBYSxFQUFFLENBQUM7b0JBQ3BDLEtBQUssQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFBO29CQUNyQyxJQUFJLFNBQVMsQ0FBQyxTQUFTO3dCQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFBO2dCQUMvRCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUMsQ0FBQTtRQUVELEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxDQUFDLFNBQVM7WUFBRSxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDOUosS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQTtJQUMxQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILHNCQUFzQixDQUFDLElBQUk7UUFDekIsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLFNBQVMsSUFBSSw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLCtCQUErQixDQUFDLENBQUE7UUFDbEksS0FBSyxNQUFNLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxJQUFJLElBQUksQ0FBQyxRQUFRO1lBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQy9FLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsV0FBVyxDQUFDLElBQUk7UUFDZCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQ2xFLEtBQUssQ0FBQyxJQUFJLElBQUksU0FBUyxJQUFJLDRCQUE0QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNuRixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILFdBQVcsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVM7UUFDckMsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLFFBQVEsQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxRQUFRLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLElBQUksUUFBUSxDQUFDLEtBQUs7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSwrQkFBK0IsQ0FBQyxDQUFBO1FBQ3hKLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDckMsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUU3QyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDLE1BQU07WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFBO1FBQ3BGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxtREFBbUQsQ0FBQyxDQUFBO1FBQ3pJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDNUIsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsRUFBRSxLQUFLLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSztnQkFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSwwQkFBMEIsQ0FBQyxDQUFBO1lBQ25MLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQTtRQUNsRCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLElBQUk7UUFDVixPQUFPLElBQUksQ0FBQyxJQUFJLElBQUksc0JBQXNCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLElBQUksaUJBQWlCLENBQUE7SUFDOUYsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxtQkFBbUIsQ0FBQyxRQUFRO1FBQzFCLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksU0FBUyxJQUFJLDRCQUE0QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNySCwwQkFBMEI7UUFDMUIsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFBO1FBQ3JCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQTtRQUVkLE9BQU8sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFBRSxNQUFNLEVBQUUsQ0FBQTtRQUNyRSxPQUFPLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0IsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUE7WUFDN0IsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxTQUFTLElBQUksb0ZBQW9GLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtZQUVwSixJQUFJLENBQUMsS0FBSztnQkFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSw0Q0FBNEMsQ0FBQyxDQUFBO1lBQzFFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQTtZQUN2QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFBO1lBRXRDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO1lBQ3JDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtZQUMvQixPQUFPLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQUUsTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1lBQ3BILE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFBO1lBRWhDLElBQUksQ0FBQyxRQUFRO2dCQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLDBCQUEwQixDQUFDLENBQUE7WUFDM0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQTtZQUUxQyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLElBQUksQ0FBQztnQkFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSw4QkFBOEIsQ0FBQyxDQUFBO1lBQzVGLElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxrQkFBa0IsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQUUsTUFBTSxFQUFFLENBQUE7WUFDbEcsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUE7WUFFM0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLGdEQUFnRCxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLEtBQUssRUFBRSxxQkFBcUIsQ0FBQyxDQUFBO1lBQ2hMLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUE7WUFDakMsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUE7WUFDaEMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUM1QixDQUFDO1FBQ0QsT0FBTyxVQUFVLENBQUE7SUFDbkIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxvQkFBb0IsQ0FBQyxJQUFJO1FBQ3ZCLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxhQUFhO1lBQUUsT0FBTyxLQUFLLENBQUE7UUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDLEtBQUssRUFBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLElBQUksWUFBWSxDQUFDLEVBQUUsSUFBSSxDQUFBO1FBQy9FLE1BQU0sSUFBSSxHQUFHLFVBQVUsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBQyxLQUFLLEVBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxJQUFJLFlBQVksQ0FBQyxFQUFFLElBQUksQ0FBQTtRQUVoRixPQUFPLElBQUksRUFBRSxJQUFJLElBQUksWUFBWSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLHNCQUFzQixDQUFDLENBQUE7SUFDekYsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsYUFBYSxDQUFDLEtBQUssRUFBRSxNQUFNO1FBQ3pCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQzVCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFBO1FBQ2pELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFBO1FBQ3JELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDaEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDckMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFFN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDekMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUE7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNmLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsK0JBQStCLENBQUMsQ0FBQTtRQUN6SSxJQUFJLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUM5QixJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUU1QixJQUFJLE1BQU0sRUFBRSxJQUFJLElBQUksY0FBYyxJQUFJLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDM0YsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUE7WUFDakQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUE7WUFFOUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7WUFDM0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQzNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDckMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxrQkFBa0IsQ0FBQTtZQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7WUFFekQsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLFlBQVksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUk7Z0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsOEJBQThCLENBQUMsQ0FBQTtZQUMvRyxJQUFJLElBQUk7Z0JBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtZQUN6QyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksb0JBQW9CO2dCQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLENBQUE7WUFDN0UsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDbEQsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFBO1lBRWQsT0FBTyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUFFLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQTtZQUN2SCxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7Z0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMkJBQTJCLENBQUMsQ0FBQTtZQUM3RSxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7WUFFakMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQ3RELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDMUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7WUFDekMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFFM0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUE7WUFDeEMsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLFlBQVksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUk7Z0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtZQUN2RyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxtQkFBbUIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQ2xELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDbkMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUE7WUFDM0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDM0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUE7WUFFL0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFBO1lB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O1FBQ2YsSUFBSSxNQUFNLENBQUMsU0FBUyxJQUFJLEtBQUssWUFBWSxxQkFBcUIsSUFBSSxLQUFLLENBQUMsUUFBUSxJQUFJLEtBQUs7WUFDdkYsS0FBSyxDQUFDLElBQUksSUFBSSxhQUFhLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1lBQ3BFLE9BQU8saUJBQWlCLENBQUMsS0FBSyxFQUFFLHVDQUF1QyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsS0FBSyxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBQ3hJLENBQUM7UUFDRCxNQUFNLEtBQUssQ0FBQTtJQUNiLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7Z2VuZXJhdGVDcHB9IGZyb20gXCIuLi9iYWNrZW5kcy9jcHAuanNcIlxuaW1wb3J0IHtPcmRlcmVkRXhwcmVzc2lvblBsYW5uZXJ9IGZyb20gXCIuLi9iYWNrZW5kcy9vcmRlcmVkLWV4cHJlc3Npb25zLmpzXCJcbmltcG9ydCB7bWF4aW11bUNwcFNvdXJjZUxlbmd0aH0gZnJvbSBcIi4uL2JhY2tlbmRzL2NwcC12YWxpZGF0aW9uLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVOYXRpdmVHcmFwaH0gZnJvbSBcIi4uL2JhY2tlbmRzL25hdGl2ZS12YWxpZGF0aW9uLmpzXCJcbmltcG9ydCB7Y3BwUnVudGltZX0gZnJvbSBcIi4uL2JhY2tlbmRzL2NwcC1ydW50aW1lLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVCYWNrZW5kTW9kdWxlfSBmcm9tIFwiLi4vYmFja2VuZHMvc2hhcmVkLmpzXCJcbmltcG9ydCB7aXNDcHBJZGVudGlmaWVyfSBmcm9tIFwiLi4vYmFja2VuZHMvaWRlbnRpZmllcnMuanNcIlxuaW1wb3J0IHtwYXJzZUNwcENzdH0gZnJvbSBcIi4vY3BwLXBhcnNlci5qc1wiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBTZW1hbnRpZm9sZERpYWdub3N0aWMsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2NyZWF0ZUNvb3JkaW5hdGVJbmRleCwgaW5kZXhlZFBvaW50QXR9IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVQYXJzZWRNb2R1bGV9IGZyb20gXCIuLi9zZW1hbnRpYy92YWxpZGF0ZS5qc1wiXG5pbXBvcnQge3NvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vY3BwLXBhcnNlci5qc1wiKS5Dc3ROb2RlfSBDc3ROb2RlICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IEV4cHJlc3Npb24gKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBTdGF0ZW1lbnQgKi9cblxuY29uc3QgYmluYXJ5T3BlcmF0aW9ucyA9IG5ldyBNYXAoW1xuICBbXCIrXCIsIFwiQWRkXCJdLCBbXCItXCIsIFwiU3VidHJhY3RcIl0sIFtcIipcIiwgXCJNdWx0aXBseVwiXSwgW1wiPT1cIiwgXCJFcXVhbFwiXSwgW1wiIT1cIiwgXCJOb3RFcXVhbFwiXSxcbiAgW1wiPFwiLCBcIkxlc3NUaGFuXCJdLCBbXCI8PVwiLCBcIkxlc3NUaGFuT3JFcXVhbFwiXSwgW1wiPlwiLCBcIkdyZWF0ZXJUaGFuXCJdLCBbXCI+PVwiLCBcIkdyZWF0ZXJUaGFuT3JFcXVhbFwiXSxcbiAgW1wiJiZcIiwgXCJBbmRcIl0sIFtcInx8XCIsIFwiT3JcIl1cbl0pXG5jb25zdCBoZWxwZXJzID0gbmV3IE1hcChbXG4gIFtcInNlbWFudGlmb2xkX2ludGVnZXJfYWRkXCIsIFwiUGhwQWRkXCJdLCBbXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX3N1YnRyYWN0XCIsIFwiU3VidHJhY3RcIl0sXG4gIFtcInNlbWFudGlmb2xkX2ludGVnZXJfbXVsdGlwbHlcIiwgXCJNdWx0aXBseVwiXSwgW1wic2VtYW50aWZvbGRfc3RyaW5nX2NvbmNhdFwiLCBcIlN0cmluZ0NvbmNhdFwiXSxcbiAgW1wic2VtYW50aWZvbGRfc3RyaW5nX2VxdWFsXCIsIFwiU3RyaW5nRXF1YWxcIl0sIFtcInNlbWFudGlmb2xkX3N0cmluZ19ub3RfZXF1YWxcIiwgXCJTdHJpbmdOb3RFcXVhbFwiXVxuXSlcblxuLyoqIFN0cmljdCBmaWVsZC1hbmQtdG9rZW4gY29uc3VtZXIgZm9yIHRoZSBwcml2YXRlIGZyb3plbiBDUFAgQ1NULiAqL1xuZXhwb3J0IGNsYXNzIENwcFJlYWRlciB7XG4gIC8qKlxuICAgKiBPd25zIHNvdXJjZSBjb250ZW50IGFuZCBpdHMgY29vcmRpbmF0ZSBpbmRleCwgbmV2ZXIgbmF0aXZlIHBhcnNlciBoYW5kbGVzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBPcmlnaW5hbCBmaWxlbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIEV4YWN0IG9yaWdpbmFsIHNvdXJjZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgICB0aGlzLmZpbGVuYW1lID0gZmlsZW5hbWVcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZVxuICAgIHRoaXMuY29vcmRpbmF0ZXMgPSBjcmVhdGVDb29yZGluYXRlSW5kZXgoc291cmNlKVxuICAgIHRoaXMuZ2VuZXJhdGVkID0gZmFsc2VcbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIEV4cHJlc3Npb24+IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnMgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge1NldDxzdHJpbmc+IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMudGVtcG9yYXJ5TmFtZXMgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge01hcDxTdGF0ZW1lbnQsIHtub2RlOiBDc3ROb2RlLCB0eXBlOiBzdHJpbmd9Pn0gKi9cbiAgICB0aGlzLnByaW50VHlwZXMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge1NldDxzdHJpbmc+fSAqL1xuICAgIHRoaXMuZGVjbGFyZWRGdW5jdGlvbnMgPSBuZXcgU2V0KClcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2NhdGVzIG9uZSBwYXJzZXItb3duZWQgcmFuZ2UgaW4gVVRGLTE2IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBQYXJzZXIgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBWZXJpZmllZCBsb2NhdGlvbi5cbiAgICovXG4gIGxvY2F0aW9uKG5vZGUpIHtcbiAgICByZXR1cm4ge2ZpbGVuYW1lOiB0aGlzLmZpbGVuYW1lLCBzdGFydDogaW5kZXhlZFBvaW50QXQodGhpcy5jb29yZGluYXRlcywgbm9kZS5zdGFydEluZGV4KSwgZW5kOiBpbmRleGVkUG9pbnRBdCh0aGlzLmNvb3JkaW5hdGVzLCBub2RlLmVuZEluZGV4KX1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBvbmx5IHRoZSBzcGVsbGluZyBvZiBhbiBhbHJlYWR5IHJlY29nbml6ZWQgcGFyc2VyIG5vZGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBFeGFjdCB0b2tlbiBzcGVsbGluZy5cbiAgICovXG4gIHRleHQobm9kZSkge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZS5zbGljZShub2RlLnN0YXJ0SW5kZXgsIG5vZGUuZW5kSW5kZXgpXG4gIH1cblxuICAvKipcbiAgICogUmVqZWN0cyBhIGxvY2F0ZWQgc291cmNlLXByb2ZpbGUgdmlvbGF0aW9uLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBSZWplY3RlZCBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RldGFpbF0gLSBQcm9maWxlIHZpb2xhdGlvbi5cbiAgICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICAgKi9cbiAgZmFpbChub2RlLCBkZXRhaWwgPSBub2RlLnR5cGUpIHtcbiAgICB1bnN1cHBvcnRlZFN5bnRheChcImNwcFwiLCBkZXRhaWwsIHRoaXMubG9jYXRpb24obm9kZSkpXG4gIH1cblxuICAvKipcbiAgICogVHJhdmVyc2VzIGFsbCBlZGdlcyBiZWZvcmUgaW50ZXJwcmV0aW5nIGFueSBzb3VyY2UgbWVhbmluZy5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gQ3VycmVudCBwYXJzZXIgbm9kZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkZXB0aF0gLSBCb3VuZGVkIENTVCB0cmF2ZXJzYWwgZGVwdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgdmFsaWRhdGVUcmVlKG5vZGUsIGRlcHRoID0gMCkge1xuICAgIGlmIChkZXB0aCA+IDUxMikgdGhpcy5mYWlsKG5vZGUsIFwiQ1BQIENTVCBleGNlZWRzIHRoZSA1MTItbGV2ZWwgdHJhdmVyc2FsIGxpbWl0XCIpXG4gICAgZm9yIChjb25zdCB7bm9kZTogY2hpbGR9IG9mIG5vZGUuY2hpbGRyZW4pIHRoaXMudmFsaWRhdGVUcmVlKGNoaWxkLCBkZXB0aCArIDEpXG4gICAgaWYgKG5vZGUuZXJyb3IgfHwgbm9kZS5taXNzaW5nIHx8IG5vZGUuaGFzRXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiUEFSU0VfRVJST1JcIiwgbGFuZ3VhZ2U6IFwiY3BwXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBtZXNzYWdlOiBgQ1BQIHBhcnNlciByZWNvdmVyeSBhdCAnJHtub2RlLnR5cGV9Jy5gfSlcbiAgICB9XG4gICAgaWYgKG5vZGUuZXh0cmEgJiYgbm9kZS50eXBlICE9IFwiY29tbWVudFwiKSB0aGlzLmZhaWwobm9kZSwgXCJ1bmV4cGVjdGVkIGV4dHJhIHBhcnNlciBjaGlsZFwiKVxuICAgIGlmICgobm9kZS50eXBlID09IFwiY29tbWVudFwiIHx8IG5vZGUudHlwZSA9PSBcInN0cmluZ19jb250ZW50XCIpICYmIC9cXD9cXD9bPS8nKCkhPD4tXS91LnRlc3QodGhpcy50ZXh0KG5vZGUpKSkge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIFwidHJpZ3JhcGggcHJlcHJvY2Vzc2luZ1wiKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiY29tbWVudFwiKSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhpcy50ZXh0KG5vZGUpXG5cbiAgICAgIC8vIEEgdGVybWluYWwgQ1IgYmVsb25ncyB0byBvcmRpbmFyeSBDUkxGOyBjb250ZW50IGFmdGVyIGEgYmFyZSBDUiBpcyBub3QgYSBDUFAgbGluZSBjb21tZW50LlxuICAgICAgaWYgKC9cXFxcKD86XFxyXFxuP3xcXG4pL3UudGVzdCh0ZXh0KSB8fCB0ZXh0LnN0YXJ0c1dpdGgoXCIvL1wiKSAmJiAvXFxyKD8hXFxufCQpL3UudGVzdCh0ZXh0KSkge1xuICAgICAgICB0aGlzLmZhaWwobm9kZSwgXCJwcmVwcm9jZXNzaW5nLXNlbnNpdGl2ZSBjb21tZW50XCIpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlcGFyYXRlcyBoYXJtbGVzcyBjb21tZW50cyBhZnRlciBldmVyeSBjaGlsZCBoYXMgYmVlbiB2YWxpZGF0ZWQuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcmVudCBub2RlLlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZVtdfSBPcmRlcmVkIHN0cnVjdHVyYWwgY2hpbGRyZW4uXG4gICAqL1xuICBwYXJ0cyhub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4ubWFwKCh7bm9kZTogY2hpbGR9KSA9PiBjaGlsZCkuZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyBvbmUgZXhhY3QgZmllbGQgcmF0aGVyIHRoYW4gc2VhcmNoaW5nIGRlc2NlbmRhbnRzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBGaWVsZCBvd25lci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBGaWVsZCBuYW1lLlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZX0gU29sZSBmaWVsZCBjaGlsZC5cbiAgICovXG4gIGZpZWxkKG5vZGUsIG5hbWUpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gbm9kZS5jaGlsZHJlbi5maWx0ZXIoKHtmaWVsZH0pID0+IGZpZWxkID09IG5hbWUpXG5cbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggIT0gMSkgcmV0dXJuIHRoaXMuZmFpbChub2RlLCBgZXhwZWN0ZWQgb25lICcke25hbWV9JyBmaWVsZGApXG4gICAgcmV0dXJuIG1hdGNoZXNbMF0ubm9kZVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN1bWVzIGV2ZXJ5IHN0cnVjdHVyYWwgY2hpbGQsIGluY2x1ZGluZyBwdW5jdHVhdGlvbi5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gU2hhcGUgb3duZXIuXG4gICAqIEBwYXJhbSB7KENzdE5vZGUgfCBzdHJpbmcpW119IGV4cGVjdGVkIC0gT3JkZXJlZCBub2RlcyBvciB0b2tlbiBraW5kcy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzaGFwZShub2RlLCBleHBlY3RlZCkge1xuICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKGNoaWxkcmVuLmxlbmd0aCAhPSBleHBlY3RlZC5sZW5ndGggfHwgY2hpbGRyZW4uc29tZSgoY2hpbGQsIGluZGV4KSA9PlxuICAgICAgdHlwZW9mIGV4cGVjdGVkW2luZGV4XSA9PSBcInN0cmluZ1wiID8gY2hpbGQudHlwZSAhPSBleHBlY3RlZFtpbmRleF0gOiBjaGlsZCAhPT0gZXhwZWN0ZWRbaW5kZXhdKSkgdGhpcy5mYWlsKG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVzIGFuIG9yZGluYXJ5IGNhbGxlciBpZGVudGlmaWVyIG91dHNpZGUgdGhlIHByb3RlY3RlZCBuYW1lc3BhY2UuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIElkZW50aWZpZXIgdG9rZW4uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IEFjY2VwdGVkIHNwZWxsaW5nLlxuICAgKi9cbiAgaWRlbnRpZmllcihub2RlKSB7XG4gICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dChub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fCAhaXNDcHBJZGVudGlmaWVyKG5hbWUpKSB0aGlzLmZhaWwobm9kZSwgXCJyZXNlcnZlZCBvciB1bnN1cHBvcnRlZCBpZGVudGlmaWVyXCIpXG4gICAgcmV0dXJuIG5hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmx5IHRoZSBjYW5vbmljYWwgc2NhbGFyIHR5cGUgc3BlbGxpbmdzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBUeXBlIHRva2VuLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gU2VtYW50aWMgc2NhbGFyLlxuICAgKi9cbiAgdHlwZShub2RlKSB7XG4gICAgY29uc3Qgc3BlbGxpbmcgPSBub2RlLnR5cGUgPT0gXCJxdWFsaWZpZWRfaWRlbnRpZmllclwiID8gdGhpcy5xdWFsaWZpZWQobm9kZSkgOiB0aGlzLnRleHQobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJxdWFsaWZpZWRfaWRlbnRpZmllclwiICYmIChub2RlLnR5cGUgIT0gXCJwcmltaXRpdmVfdHlwZVwiIHx8IHNwZWxsaW5nICE9IFwiYm9vbFwiKSkgdGhpcy5mYWlsKG5vZGUsIFwic2NhbGFyIHR5cGUgc2hhcGVcIilcbiAgICBjb25zdCB0eXBlID0gc291cmNlU2NhbGFyVHlwZShcImNwcFwiLCBzcGVsbGluZywgdGhpcy5sb2NhdGlvbihub2RlKSlcblxuICAgIGlmICghdHlwZSkgcmV0dXJuIHRoaXMuZmFpbChub2RlLCBcInVuc3VwcG9ydGVkIHNjYWxhciB0eXBlXCIpXG4gICAgcmV0dXJuIHR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBleGFjdGx5IG9uZSBzdGQtcXVhbGlmaWVkIHNjYWxhciBuYW1lIGZyb20gQ1BQIGZpZWxkcyBhbmQgcHVuY3R1YXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFF1YWxpZmllZCBncmFtbWFyIG5vZGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IENhbm9uaWNhbCBxdWFsaWZpZWQgc2NhbGFyIHNwZWxsaW5nLlxuICAgKi9cbiAgcXVhbGlmaWVkKG5vZGUpIHtcbiAgICBjb25zdCBzY29wZSA9IHRoaXMuZmllbGQobm9kZSwgXCJzY29wZVwiKVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwibmFtZVwiKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbc2NvcGUsIFwiOjpcIiwgbmFtZV0pXG4gICAgaWYgKHNjb3BlLnR5cGUgIT0gXCJuYW1lc3BhY2VfaWRlbnRpZmllclwiIHx8IHRoaXMudGV4dChzY29wZSkgIT0gXCJzdGRcIiB8fFxuICAgICAgIVtcInR5cGVfaWRlbnRpZmllclwiLCBcImlkZW50aWZpZXJcIl0uaW5jbHVkZXMobmFtZS50eXBlKSB8fCAhW1wiaW50NjRfdFwiLCBcInN0cmluZ1wiXS5pbmNsdWRlcyh0aGlzLnRleHQobmFtZSkpKSB0aGlzLmZhaWwobm9kZSwgXCJxdWFsaWZpZWQgc2NhbGFyIG5hbWVcIilcbiAgICByZXR1cm4gXCJzdGQ6OlwiICsgdGhpcy50ZXh0KG5hbWUpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBkaXJlY3QgZnVuY3Rpb24gY2FsbCdzIGV4YWN0IGFyZ3VtZW50IGxpc3QuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIENhbGwgbm9kZS5cbiAgICogQHJldHVybnMge3tuYW1lOiBDc3ROb2RlLCBhcmd1bWVudHM6IENzdE5vZGVbXX19IFBhcnNlZCBjYWxsIHNoYXBlLlxuICAgKi9cbiAgY2FsbChub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImNhbGxfZXhwcmVzc2lvblwiKSByZXR1cm4gdGhpcy5mYWlsKG5vZGUsIFwiZGlyZWN0IGNhbGwgcmVxdWlyZWRcIilcbiAgICBjb25zdCBuYW1lID0gdGhpcy5maWVsZChub2RlLCBcImZ1bmN0aW9uXCIpXG4gICAgY29uc3QgbGlzdCA9IHRoaXMuZmllbGQobm9kZSwgXCJhcmd1bWVudHNcIilcblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW25hbWUsIGxpc3RdKVxuICAgIGlmICghW1wiaWRlbnRpZmllclwiLCBcInF1YWxpZmllZF9pZGVudGlmaWVyXCJdLmluY2x1ZGVzKG5hbWUudHlwZSkgfHwgbGlzdC50eXBlICE9IFwiYXJndW1lbnRfbGlzdFwiKSB0aGlzLmZhaWwobm9kZSwgXCJkaXJlY3QgY2FsbCBzaGFwZVwiKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhsaXN0KVxuICAgIGNvbnN0IGFyZ3MgPSBwYXJ0cy5zbGljZSgxLCAtMSkuZmlsdGVyKChfcGFydCwgaW5kZXgpID0+IGluZGV4ICUgMiA9PSAwKVxuXG4gICAgdGhpcy5zaGFwZShsaXN0LCBbXCIoXCIsIC4uLmFyZ3MuZmxhdE1hcCgoYXJnLCBpbmRleCkgPT4gaW5kZXggPT0gMCA/IFthcmddIDogW1wiLFwiLCBhcmddKSwgXCIpXCJdKVxuICAgIHJldHVybiB7YXJndW1lbnRzOiBhcmdzLCBuYW1lfVxuICB9XG5cbiAgLyoqXG4gICAqIERlY29kZXMgYSBwYXJzZXItYmFja2VkIG9yZGluYXJ5IENQUCBzdHJpbmcgdG9rZW4gYXMgVVRGLTggYnl0ZXMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFN0cmluZyBsaXRlcmFsLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBDb21wbGV0ZSBVbmljb2RlIHNjYWxhciB2YWx1ZS5cbiAgICovXG4gIHN0cmluZyhub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcInN0cmluZ19saXRlcmFsXCIpIHJldHVybiB0aGlzLmZhaWwobm9kZSwgXCJvcmRpbmFyeSBzdHJpbmcgbGl0ZXJhbCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKHBhcnRzWzBdPy50eXBlICE9ICdcIicgfHwgcGFydHMuYXQoLTEpPy50eXBlICE9ICdcIicpIHRoaXMuZmFpbChub2RlLCBcInByZWZpeGVkIHN0cmluZyBsaXRlcmFsXCIpXG4gICAgY29uc3QgYnl0ZXMgPSBbXVxuXG4gICAgZm9yIChsZXQgaW5kZXggPSAxOyBpbmRleCA8IHBhcnRzLmxlbmd0aCAtIDE7IGluZGV4KyspIHtcbiAgICAgIGNvbnN0IGNoaWxkID0gcGFydHNbaW5kZXhdXG4gICAgICBjb25zdCB0ZXh0ID0gdGhpcy50ZXh0KGNoaWxkKVxuXG4gICAgICBpZiAoY2hpbGQudHlwZSA9PSBcInN0cmluZ19jb250ZW50XCIpIHtcbiAgICAgICAgaWYgKC9bXFxyXFxuXS91LnRlc3QodGV4dCkpIHRoaXMuZmFpbChjaGlsZCwgXCJyYXcgbGluZSB0ZXJtaW5hdG9yIGluIHN0cmluZyBsaXRlcmFsXCIpXG4gICAgICAgIGZvciAoY29uc3QgYnl0ZSBvZiBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUodGV4dCkpIGJ5dGVzLnB1c2goYnl0ZSlcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGNoaWxkLnR5cGUgPT0gXCJlc2NhcGVfc2VxdWVuY2VcIikge1xuICAgICAgICBjb25zdCBzaW1wbGUgPSBuZXcgTWFwKFtbXCJhXCIsIDddLCBbXCJiXCIsIDhdLCBbXCJmXCIsIDEyXSwgW1wiblwiLCAxMF0sIFtcInJcIiwgMTNdLCBbXCJ0XCIsIDldLCBbXCJ2XCIsIDExXSwgW1wiXFxcXFwiLCA5Ml0sIFsnXCInLCAzNF0sIFtcIidcIiwgMzldLCBbXCI/XCIsIDYzXV0pXG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGV4dC5zbGljZSgxKVxuXG4gICAgICAgIGlmICh0ZXh0WzBdICE9IFwiXFxcXFwiKSB0aGlzLmZhaWwoY2hpbGQsIFwiaW52YWxpZCBlc2NhcGVcIilcbiAgICAgICAgaWYgKHNpbXBsZS5oYXModmFsdWUpKSBieXRlcy5wdXNoKC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAoc2ltcGxlLmdldCh2YWx1ZSkpKVxuICAgICAgICBlbHNlIGlmICgvXlswLTddezEsM30kL3UudGVzdCh2YWx1ZSkgfHwgL154WzAtOWEtZkEtRl0rJC91LnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgY29uc3QgbmV4dCA9IHBhcnRzW2luZGV4ICsgMV1cblxuICAgICAgICAgIC8vIENQUCBjb25zdW1lcyBldmVyeSBhZGphY2VudCBoZXggZGlnaXQ7IHRoZSBmcm96ZW4gZ3JhbW1hciBjYXBzIGVhY2ggZXNjYXBlIG5vZGUgYXQgZm91ci5cbiAgICAgICAgICBpZiAodmFsdWUuc3RhcnRzV2l0aChcInhcIikgJiYgbmV4dC50eXBlID09IFwic3RyaW5nX2NvbnRlbnRcIiAmJiBuZXh0LnN0YXJ0SW5kZXggPT0gY2hpbGQuZW5kSW5kZXggJiYgL15bMC05YS1mQS1GXS91LnRlc3QodGhpcy50ZXh0KG5leHQpKSkge1xuICAgICAgICAgICAgdGhpcy5mYWlsKGNoaWxkLCBcImhleGFkZWNpbWFsIGVzY2FwZSBzcGxpdCBieSBwYXJzZXIgYm91bmRhcnlcIilcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgbnVtYmVyID0gTnVtYmVyLnBhcnNlSW50KHZhbHVlWzBdID09IFwieFwiID8gdmFsdWUuc2xpY2UoMSkgOiB2YWx1ZSwgdmFsdWVbMF0gPT0gXCJ4XCIgPyAxNiA6IDgpXG5cbiAgICAgICAgICBpZiAobnVtYmVyID4gMjU1KSB0aGlzLmZhaWwoY2hpbGQsIFwiZXNjYXBlIG91dHNpZGUgYnl0ZSByYW5nZVwiKVxuICAgICAgICAgIGJ5dGVzLnB1c2gobnVtYmVyKVxuICAgICAgICB9IGVsc2UgdGhpcy5mYWlsKGNoaWxkLCBcInVuc3VwcG9ydGVkIGVzY2FwZVwiKVxuICAgICAgfSBlbHNlIHRoaXMuZmFpbChjaGlsZCwgXCJzdHJpbmcgY2hpbGRcIilcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBuZXcgVGV4dERlY29kZXIoXCJ1dGYtOFwiLCB7ZmF0YWw6IHRydWUsIGlnbm9yZUJPTTogdHJ1ZX0pLmRlY29kZShuZXcgVWludDhBcnJheShieXRlcykpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFR5cGVFcnJvcikgcmV0dXJuIHRoaXMuZmFpbChub2RlLCBcImludmFsaWQgVVRGLTggbGl0ZXJhbCBieXRlc1wiKVxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgc3VwcG9ydGVkIGV4cHJlc3Npb25zIHdpdGhvdXQgYXNzdW1pbmcgQ1BQIGFyZ3VtZW50IGV2YWx1YXRpb24gb3JkZXIuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEV4cHJlc3Npb24gbm9kZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbbmVzdGVkXSAtIFdoZXRoZXIgYSBzZW1hbnRpYyBjYWxsIHdvdWxkIGhhdmUgdW5zcGVjaWZpZWQgb3JkZXIuXG4gICAqIEByZXR1cm5zIHtFeHByZXNzaW9ufSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgZXhwcmVzc2lvbihub2RlLCBuZXN0ZWQgPSBmYWxzZSkge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImNvbmRpdGlvbl9jbGF1c2VcIikge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwidmFsdWVcIilcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCIoXCIsIHZhbHVlLCBcIilcIl0pXG4gICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uKHZhbHVlLCBuZXN0ZWQpXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJwYXJlbnRoZXNpemVkX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiKFwiLCBwYXJ0c1sxXSwgXCIpXCJdKVxuICAgICAgcmV0dXJuIHRoaXMuZXhwcmVzc2lvbihwYXJ0c1sxXSwgbmVzdGVkKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiaWRlbnRpZmllclwiKSB7XG4gICAgICBjb25zdCB0ZW1wb3JhcnkgPSB0aGlzLnRlbXBvcmFyeUV4cHJlc3Npb25zPy5nZXQodGhpcy50ZXh0KG5vZGUpKVxuXG4gICAgICBpZiAodGVtcG9yYXJ5KSB7XG4gICAgICAgIHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnM/LmRlbGV0ZSh0aGlzLnRleHQobm9kZSkpXG4gICAgICAgIHJldHVybiB0ZW1wb3JhcnlcbiAgICAgIH1cbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIsIGxvY2F0aW9uLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIobm9kZSl9LCB7bmFtZTogbG9jYXRpb259KVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwidHJ1ZVwiIHx8IG5vZGUudHlwZSA9PSBcImZhbHNlXCIpIHtcbiAgICAgIGlmICh0aGlzLnRleHQobm9kZSkgIT0gbm9kZS50eXBlKSB0aGlzLmZhaWwobm9kZSwgXCJub25jYW5vbmljYWwgQm9vbGVhbiBsaXRlcmFsIHNwZWxsaW5nXCIpXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJCb29sZWFuTGl0ZXJhbFwiLCBsb2NhdGlvbiwgdmFsdWU6IG5vZGUudHlwZSA9PSBcInRydWVcIn0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJudW1iZXJfbGl0ZXJhbFwiKSB0aGlzLmZhaWwobm9kZSwgXCJpbnRlZ2VyIGxpdGVyYWwgcmVxdWlyZXMgZXhhY3Qgc3RkOjppbnQ2NF90IGNvbnN0cnVjdGlvblwiKVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJiaW5hcnlfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWVsZChub2RlLCBcImxlZnRcIilcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChub2RlLCBcInJpZ2h0XCIpXG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQobm9kZSwgXCJvcGVyYXRvclwiKVxuICAgICAgY29uc3QgaW50ZW50ID0gYmluYXJ5T3BlcmF0aW9ucy5nZXQob3BlcmF0b3IudHlwZSlcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbbGVmdCwgb3BlcmF0b3IsIHJpZ2h0XSlcbiAgICAgIGlmICghaW50ZW50KSByZXR1cm4gdGhpcy5mYWlsKG9wZXJhdG9yLCBcInVuc3VwcG9ydGVkIGJpbmFyeSBvcGVyYXRvclwiKVxuICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5KG5vZGUsIGludGVudCwgdGhpcy5leHByZXNzaW9uKGxlZnQsIHRydWUpLCB0aGlzLmV4cHJlc3Npb24ocmlnaHQsIHRydWUpLCBvcGVyYXRvcilcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInVuYXJ5X2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLmZpZWxkKG5vZGUsIFwib3BlcmF0b3JcIilcbiAgICAgIGNvbnN0IGFyZ3VtZW50ID0gdGhpcy5maWVsZChub2RlLCBcImFyZ3VtZW50XCIpXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW29wZXJhdG9yLCBhcmd1bWVudF0pXG4gICAgICBpZiAoIVtcIi1cIiwgXCIhXCJdLmluY2x1ZGVzKG9wZXJhdG9yLnR5cGUpKSB0aGlzLmZhaWwob3BlcmF0b3IsIFwidW5zdXBwb3J0ZWQgdW5hcnkgb3BlcmF0b3JcIilcbiAgICAgIHJldHVybiB0aGlzLnVuYXJ5KG5vZGUsIG9wZXJhdG9yLnR5cGUgPT0gXCItXCIgPyBcIk5lZ2F0ZVwiIDogXCJOb3RcIiwgdGhpcy5leHByZXNzaW9uKGFyZ3VtZW50LCB0cnVlKSwgb3BlcmF0b3IpXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJjYWxsX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgY2FsbCA9IHRoaXMuY2FsbChub2RlKVxuICAgICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dChjYWxsLm5hbWUpXG5cbiAgICAgIGlmIChjYWxsLm5hbWUudHlwZSA9PSBcInF1YWxpZmllZF9pZGVudGlmaWVyXCIpIHtcbiAgICAgICAgY29uc3QgcXVhbGlmaWVkID0gdGhpcy5xdWFsaWZpZWQoY2FsbC5uYW1lKVxuXG4gICAgICAgIGlmIChxdWFsaWZpZWQgPT0gXCJzdGQ6OmludDY0X3RcIikge1xuICAgICAgICAgIGlmIChjYWxsLmFyZ3VtZW50cy5sZW5ndGggIT0gMSB8fCBjYWxsLmFyZ3VtZW50c1swXS50eXBlICE9IFwibnVtYmVyX2xpdGVyYWxcIikgdGhpcy5mYWlsKG5vZGUsIFwiZXhhY3QgaW50ZWdlciBsaXRlcmFsIGNvbnN0cnVjdGlvblwiKVxuICAgICAgICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KGNhbGwuYXJndW1lbnRzWzBdKVxuXG4gICAgICAgICAgaWYgKCEvXig/OjB8WzEtOV1bMC05XSopJC91LnRlc3Qoc3BlbGxpbmcpIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihOdW1iZXIoc3BlbGxpbmcpKSkgdGhpcy5mYWlsKGNhbGwuYXJndW1lbnRzWzBdLCBcIm5vbi1zYWZlIG9yIG5vbmNhbm9uaWNhbCBpbnRlZ2VyXCIpXG4gICAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiSW50ZWdlckxpdGVyYWxcIiwgbG9jYXRpb24sIHZhbHVlOiBOdW1iZXIoc3BlbGxpbmcpfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICAgICAgfVxuICAgICAgICBpZiAocXVhbGlmaWVkID09IFwic3RkOjpzdHJpbmdcIikge1xuICAgICAgICAgIGlmIChjYWxsLmFyZ3VtZW50cy5sZW5ndGggIT0gMiB8fCBjYWxsLmFyZ3VtZW50c1sxXS50eXBlICE9IFwibnVtYmVyX2xpdGVyYWxcIikgdGhpcy5mYWlsKG5vZGUsIFwiYnl0ZS1jb3VudGVkIHN0cmluZyBsaXRlcmFsIGNvbnN0cnVjdGlvblwiKVxuICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5zdHJpbmcoY2FsbC5hcmd1bWVudHNbMF0pXG4gICAgICAgICAgY29uc3QgbGVuZ3RoID0gdGhpcy50ZXh0KGNhbGwuYXJndW1lbnRzWzFdKVxuXG4gICAgICAgICAgaWYgKGxlbmd0aCAhPSBTdHJpbmcoQnVmZmVyLmJ5dGVMZW5ndGgodmFsdWUsIFwidXRmOFwiKSkpIHRoaXMuZmFpbChub2RlLCBcInN0cmluZyBsaXRlcmFsIGJ5dGUgY291bnRcIilcbiAgICAgICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJTdHJpbmdMaXRlcmFsXCIsIGxvY2F0aW9uLCB2YWx1ZX0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJxdWFsaWZpZWQgdXNlciBjYWxsXCIpXG4gICAgICB9XG4gICAgICAvLyBHZW5lcmF0ZWQgb3BlcmF0aW9ucyBhcmUgc2VwYXJhdGUgdGVtcG9yYXJ5IGluaXRpYWxpemVyczsgb25seSBleGFjdCBzY2FsYXIgbGl0ZXJhbCBjb25zdHJ1Y3Rpb25zIG1heSBuZXN0IGFzIGNhbGxzLlxuICAgICAgaWYgKG5lc3RlZCkgdGhpcy5mYWlsKG5vZGUsIFwiY2FsbGVyIGNhbGwgaW4gdW5zcGVjaWZpZWQtb3JkZXIgZXhwcmVzc2lvblwiKVxuICAgICAgaWYgKG5hbWUgPT0gXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX25lZ2F0ZVwiKSB7XG4gICAgICAgIGlmIChjYWxsLmFyZ3VtZW50cy5sZW5ndGggIT0gMSkgdGhpcy5mYWlsKG5vZGUsIFwibmVnYXRpb24gaGVscGVyIGFyaXR5XCIpXG4gICAgICAgIHJldHVybiB0aGlzLnVuYXJ5KG5vZGUsIFwiTmVnYXRlXCIsIHRoaXMuZXhwcmVzc2lvbihjYWxsLmFyZ3VtZW50c1swXSwgdHJ1ZSksIGNhbGwubmFtZSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IGludGVudCA9IGhlbHBlcnMuZ2V0KG5hbWUpXG5cbiAgICAgIGlmIChpbnRlbnQpIHtcbiAgICAgICAgaWYgKGNhbGwuYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB0aGlzLmZhaWwobm9kZSwgXCJzY2FsYXIgaGVscGVyIGFyaXR5XCIpXG4gICAgICAgIHJldHVybiB0aGlzLmJpbmFyeShub2RlLCBpbnRlbnQsIHRoaXMuZXhwcmVzc2lvbihjYWxsLmFyZ3VtZW50c1swXSwgdHJ1ZSksIHRoaXMuZXhwcmVzc2lvbihjYWxsLmFyZ3VtZW50c1sxXSwgdHJ1ZSksIGNhbGwubmFtZSlcbiAgICAgIH1cbiAgICAgIGlmIChjYWxsLmFyZ3VtZW50cy5sZW5ndGggIT0gMikgdGhpcy5mYWlsKG5vZGUsIFwic2VtYW50aWMgY2FsbCBhcml0eVwiKVxuICAgICAgY29uc3QgY2FsbGVlID0gdGhpcy5pZGVudGlmaWVyKGNhbGwubmFtZSlcblxuICAgICAgaWYgKCF0aGlzLmdlbmVyYXRlZCAmJiAhdGhpcy5kZWNsYXJlZEZ1bmN0aW9ucy5oYXMoY2FsbGVlKSkgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJpbXBsaWNpdCBmdW5jdGlvbiBkZWNsYXJhdGlvblwiKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiQ2FsbEV4cHJlc3Npb25cIiwgbG9jYXRpb24sIGNhbGxlZSxcbiAgICAgICAgYXJndW1lbnRzOiBjYWxsLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50KSA9PiB0aGlzLmV4cHJlc3Npb24oYXJndW1lbnQsIHRydWUpKX0sIHtjYWxsZWU6IHRoaXMubG9jYXRpb24oY2FsbC5uYW1lKX0pXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmZhaWwobm9kZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIHBhcnNlciBpbnRlbnQgYmVmb3JlIHNoYXJlZCB0eXBlIHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIE93bmluZyBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaW50ZW50IC0gQWRhcHRlZCBvcGVyYXRpb24uXG4gICAqIEBwYXJhbSB7RXhwcmVzc2lvbn0gbGVmdCAtIExlZnQgb3BlcmFuZC5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSByaWdodCAtIFJpZ2h0IG9wZXJhbmQuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gb3BlcmF0b3IgLSBPcGVyYXRvciB0b2tlbi5cbiAgICogQHJldHVybnMge0V4cHJlc3Npb259IFBlbmRpbmcgYmluYXJ5IGV4cHJlc3Npb24uXG4gICAqL1xuICBiaW5hcnkobm9kZSwgaW50ZW50LCBsZWZ0LCByaWdodCwgb3BlcmF0b3IpIHtcbiAgICByZXR1cm4gLyoqIEB0eXBlIHtFeHByZXNzaW9ufSAqLyAod2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJCaW5hcnlFeHByZXNzaW9uXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBsZWZ0LCByaWdodH0sXG4gICAgICB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSksIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCIpLkFkYXB0ZWRPcGVyYXRpb259ICovIChpbnRlbnQpKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIHBhcnNlciBpbnRlbnQgZm9yIGEgdW5hcnkgb3BlcmF0aW9uLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBPd25pbmcgZXhwcmVzc2lvbi5cbiAgICogQHBhcmFtIHtcIk5lZ2F0ZVwiIHwgXCJOb3RcIn0gaW50ZW50IC0gQWRhcHRlZCBvcGVyYXRpb24uXG4gICAqIEBwYXJhbSB7RXhwcmVzc2lvbn0gb3BlcmFuZCAtIE9wZXJhbmQuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gb3BlcmF0b3IgLSBPcGVyYXRvciB0b2tlbi5cbiAgICogQHJldHVybnMge0V4cHJlc3Npb259IFBlbmRpbmcgdW5hcnkgZXhwcmVzc2lvbi5cbiAgICovXG4gIHVuYXJ5KG5vZGUsIGludGVudCwgb3BlcmFuZCwgb3BlcmF0b3IpIHtcbiAgICByZXR1cm4gLyoqIEB0eXBlIHtFeHByZXNzaW9ufSAqLyAod2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJVbmFyeUV4cHJlc3Npb25cIiwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIG9wZXJhbmR9LFxuICAgICAge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKG9wZXJhdG9yKX0pLCBpbnRlbnQpKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBpbml0aWFsaXplZCBkZWNsYXJhdGlvbiBvciBleGVjdXRhYmxlIHN0YXRlbWVudC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gU3RhdGVtZW50IG5vZGUuXG4gICAqIEByZXR1cm5zIHtTdGF0ZW1lbnR9IFNlbWFudGljIHN0YXRlbWVudC5cbiAgICovXG4gIHN0YXRlbWVudChub2RlKSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSB0aGlzLmxvY2F0aW9uKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlID09IFwiZGVjbGFyYXRpb25cIikge1xuICAgICAgY29uc3QgdHlwZU5vZGUgPSBub2RlLmNoaWxkcmVuLmZpbmQoKHtmaWVsZH0pID0+IGZpZWxkID09IFwidHlwZVwiKT8ubm9kZVxuXG4gICAgICBpZiAoIXR5cGVOb2RlKSByZXR1cm4gbWlzc2luZ1R5cGUoXCJjcHBcIiwgXCJsb2NhbFwiLCBsb2NhdGlvbilcbiAgICAgIGNvbnN0IGRlY2xhcmF0b3IgPSB0aGlzLmZpZWxkKG5vZGUsIFwiZGVjbGFyYXRvclwiKVxuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG4gICAgICBjb25zdCBpbW11dGFibGUgPSBwYXJ0c1swXS50eXBlID09IFwidHlwZV9xdWFsaWZpZXJcIlxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFsuLi4oaW1tdXRhYmxlID8gW3BhcnRzWzBdXSA6IFtdKSwgdHlwZU5vZGUsIGRlY2xhcmF0b3IsIFwiO1wiXSlcbiAgICAgIGlmIChpbW11dGFibGUgJiYgdGhpcy50ZXh0KHBhcnRzWzBdKSAhPSBcImNvbnN0XCIpIHRoaXMuZmFpbChwYXJ0c1swXSwgXCJsb2NhbCBxdWFsaWZpZXJcIilcbiAgICAgIGlmIChkZWNsYXJhdG9yLnR5cGUgIT0gXCJpbml0X2RlY2xhcmF0b3JcIikgdGhpcy5mYWlsKGRlY2xhcmF0b3IsIFwiaW5pdGlhbGl6ZWQgc2ltcGxlIGxvY2FsIHJlcXVpcmVkXCIpXG4gICAgICBjb25zdCBuYW1lID0gdGhpcy5maWVsZChkZWNsYXJhdG9yLCBcImRlY2xhcmF0b3JcIilcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5maWVsZChkZWNsYXJhdG9yLCBcInZhbHVlXCIpXG5cbiAgICAgIHRoaXMuc2hhcGUoZGVjbGFyYXRvciwgW25hbWUsIFwiPVwiLCB2YWx1ZV0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJMb2NhbERlY2xhcmF0aW9uXCIsIGxvY2F0aW9uLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIobmFtZSksIHR5cGU6IHRoaXMudHlwZSh0eXBlTm9kZSksIG11dGFibGU6ICFpbW11dGFibGUsXG4gICAgICAgIGluaXRpYWxpemVyOiB0aGlzLmV4cHJlc3Npb24odmFsdWUpfSwge25hbWU6IHRoaXMubG9jYXRpb24obmFtZSksIG9wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKHRoaXMucGFydHMoZGVjbGFyYXRvcilbMV0pfSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInJldHVybl9zdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wicmV0dXJuXCIsIHBhcnRzWzFdLCBcIjtcIl0pXG4gICAgICByZXR1cm4ge2tpbmQ6IFwiUmV0dXJuU3RhdGVtZW50XCIsIGxvY2F0aW9uLCBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24ocGFydHNbMV0pfVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiaWZfc3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGNvbmRpdGlvbiA9IHRoaXMuZmllbGQobm9kZSwgXCJjb25kaXRpb25cIilcbiAgICAgIGNvbnN0IGNvbnNlcXVlbmNlID0gdGhpcy5maWVsZChub2RlLCBcImNvbnNlcXVlbmNlXCIpXG4gICAgICBjb25zdCBhbHRlcm5hdGl2ZSA9IG5vZGUuY2hpbGRyZW4uZmluZCgoe2ZpZWxkfSkgPT4gZmllbGQgPT0gXCJhbHRlcm5hdGl2ZVwiKT8ubm9kZVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtcImlmXCIsIGNvbmRpdGlvbiwgY29uc2VxdWVuY2UsIC4uLihhbHRlcm5hdGl2ZSA/IFthbHRlcm5hdGl2ZV0gOiBbXSldKVxuICAgICAgY29uc3Qgc3RhdGVtZW50ID0ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklmU3RhdGVtZW50XCIpLCBsb2NhdGlvbiwgY29uZGl0aW9uOiB0aGlzLmV4cHJlc3Npb24oY29uZGl0aW9uKSwgY29uc2VxdWVudDogdGhpcy5ibG9jayhjb25zZXF1ZW5jZSl9XG5cbiAgICAgIGlmICghYWx0ZXJuYXRpdmUpIHJldHVybiBzdGF0ZW1lbnRcbiAgICAgIGNvbnN0IGJyYW5jaCA9IHRoaXMucGFydHMoYWx0ZXJuYXRpdmUpWzFdXG5cbiAgICAgIHRoaXMuc2hhcGUoYWx0ZXJuYXRpdmUsIFtcImVsc2VcIiwgYnJhbmNoXSlcbiAgICAgIHJldHVybiB7Li4uc3RhdGVtZW50LCBhbHRlcm5hdGU6IGJyYW5jaC50eXBlID09IFwiaWZfc3RhdGVtZW50XCJcbiAgICAgICAgPyB7a2luZDogXCJCbG9ja1wiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihicmFuY2gpLCBzdGF0ZW1lbnRzOiBbdGhpcy5zdGF0ZW1lbnQoYnJhbmNoKV19IDogdGhpcy5ibG9jayhicmFuY2gpfVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiZXhwcmVzc2lvbl9zdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHRoaXMucGFydHMobm9kZSlbMF1cblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbZXhwcmVzc2lvbiwgXCI7XCJdKVxuICAgICAgaWYgKGV4cHJlc3Npb24udHlwZSA9PSBcImFzc2lnbm1lbnRfZXhwcmVzc2lvblwiKSB7XG4gICAgICAgIGNvbnN0IGxlZnQgPSB0aGlzLmZpZWxkKGV4cHJlc3Npb24sIFwibGVmdFwiKVxuICAgICAgICBjb25zdCByaWdodCA9IHRoaXMuZmllbGQoZXhwcmVzc2lvbiwgXCJyaWdodFwiKVxuICAgICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQoZXhwcmVzc2lvbiwgXCJvcGVyYXRvclwiKVxuXG4gICAgICAgIHRoaXMuc2hhcGUoZXhwcmVzc2lvbiwgW2xlZnQsIFwiPVwiLCByaWdodF0pXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIobGVmdCksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKGxlZnQpfSwge25hbWU6IHRoaXMubG9jYXRpb24obGVmdCl9KVxuXG4gICAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIiwgbG9jYXRpb24sIHRhcmdldCwgZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9uKHJpZ2h0KX0sIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KVxuICAgICAgfVxuICAgICAgY29uc3QgY2FsbCA9IHRoaXMuY2FsbChleHByZXNzaW9uKVxuXG4gICAgICBpZiAoIS9ec2VtYW50aWZvbGRfcHJpbnRfKD86aW50ZWdlcnxib29sZWFufHN0cmluZykkL3UudGVzdCh0aGlzLnRleHQoY2FsbC5uYW1lKSkgfHwgY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChub2RlLCBcInByaW50IHNjYWZmb2xkXCIpXG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZXhwcmVzc2lvbihjYWxsLmFyZ3VtZW50c1swXSlcblxuICAgICAgY29uc3Qgc3RhdGVtZW50ID0ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlByaW50U3RhdGVtZW50XCIpLCBsb2NhdGlvbiwgZXhwcmVzc2lvbjogdmFsdWV9XG5cbiAgICAgIHRoaXMucHJpbnRUeXBlcy5zZXQoc3RhdGVtZW50LCB7bm9kZTogY2FsbC5uYW1lLCB0eXBlOiB0aGlzLnRleHQoY2FsbC5uYW1lKS5zbGljZShcInNlbWFudGlmb2xkX3ByaW50X1wiLmxlbmd0aCl9KVxuICAgICAgcmV0dXJuIHN0YXRlbWVudFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5mYWlsKG5vZGUpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGxleGljYWwgYnJhY2VkIGJsb2NrIGluIHNvdXJjZSBvcmRlci5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gQmxvY2sgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAgICovXG4gIGJsb2NrKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9IFwiY29tcG91bmRfc3RhdGVtZW50XCIpIHRoaXMuZmFpbChub2RlLCBcImJyYWNlZCBibG9jayByZXF1aXJlZFwiKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbXCJ7XCIsIC4uLnBhcnRzLnNsaWNlKDEsIC0xKSwgXCJ9XCJdKVxuICAgIHJldHVybiB7a2luZDogXCJCbG9ja1wiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgc3RhdGVtZW50czogdGhpcy5nZW5lcmF0ZWRcbiAgICAgID8gdGhpcy5nZW5lcmF0ZWRTdGF0ZW1lbnRzKG5vZGUuY2hpbGRyZW4ubWFwKCh7bm9kZTogY2hpbGR9KSA9PiBjaGlsZCkuc2xpY2UoMSwgLTEpKVxuICAgICAgOiBwYXJ0cy5zbGljZSgxLCAtMSkubWFwKChjaGlsZCkgPT4gdGhpcy5zdGF0ZW1lbnQoY2hpbGQpKX1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgbmFtZXNwYWNlLXNjb3BlIHNlbWFudGljIGZ1bmN0aW9uLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBGdW5jdGlvbiBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gU2VtYW50aWMgZnVuY3Rpb24uXG4gICAqL1xuICBmdW5jdGlvbihub2RlKSB7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZmllbGQobm9kZSwgXCJ0eXBlXCIpXG4gICAgY29uc3QgZGVjbGFyYXRvciA9IHRoaXMuZmllbGQobm9kZSwgXCJkZWNsYXJhdG9yXCIpXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZmllbGQobm9kZSwgXCJib2R5XCIpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFt0eXBlLCBkZWNsYXJhdG9yLCBib2R5XSlcbiAgICBpZiAoZGVjbGFyYXRvci50eXBlICE9IFwiZnVuY3Rpb25fZGVjbGFyYXRvclwiKSB0aGlzLmZhaWwobm9kZSwgXCJuYW1lc3BhY2Utc2NvcGUgZnVuY3Rpb24gcmVxdWlyZWRcIilcbiAgICBjb25zdCBuYW1lID0gdGhpcy5maWVsZChkZWNsYXJhdG9yLCBcImRlY2xhcmF0b3JcIilcbiAgICBjb25zdCBwYXJhbWV0ZXJzID0gdGhpcy5maWVsZChkZWNsYXJhdG9yLCBcInBhcmFtZXRlcnNcIilcblxuICAgIHRoaXMuc2hhcGUoZGVjbGFyYXRvciwgW25hbWUsIHBhcmFtZXRlcnNdKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhwYXJhbWV0ZXJzKVxuXG4gICAgdGhpcy5zaGFwZShwYXJhbWV0ZXJzLCBbXCIoXCIsIFwicGFyYW1ldGVyX2RlY2xhcmF0aW9uXCIsIFwiLFwiLCBcInBhcmFtZXRlcl9kZWNsYXJhdGlvblwiLCBcIilcIl0pXG4gICAgY29uc3QgY29udmVydGVkID0gW3BhcnRzWzFdLCBwYXJ0c1szXV0ubWFwKChwYXJhbWV0ZXIpID0+IHtcbiAgICAgIGNvbnN0IHR5cGVOb2RlID0gdGhpcy5maWVsZChwYXJhbWV0ZXIsIFwidHlwZVwiKVxuICAgICAgY29uc3QgbmFtZU5vZGUgPSB0aGlzLmZpZWxkKHBhcmFtZXRlciwgXCJkZWNsYXJhdG9yXCIpXG5cbiAgICAgIHRoaXMuc2hhcGUocGFyYW1ldGVyLCBbdHlwZU5vZGUsIG5hbWVOb2RlXSlcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQYXJhbWV0ZXJcIiksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKHBhcmFtZXRlciksIG5hbWU6IHRoaXMuaWRlbnRpZmllcihuYW1lTm9kZSksIHR5cGU6IHRoaXMudHlwZSh0eXBlTm9kZSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lTm9kZSl9KVxuICAgIH0pXG5cbiAgICB0aGlzLmRlY2xhcmVkRnVuY3Rpb25zLmFkZCh0aGlzLmlkZW50aWZpZXIobmFtZSkpXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgbmFtZTogdGhpcy5pZGVudGlmaWVyKG5hbWUpLCBwYXJhbWV0ZXJzOiBjb252ZXJ0ZWQsXG4gICAgICByZXR1cm5UeXBlOiB0aGlzLnR5cGUodHlwZSksIGJvZHk6IHRoaXMuYmxvY2soYm9keSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lKX0pXG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBvbmx5IHRoZSBleGFjdCBwYXJhbWV0ZXJsZXNzIG1haW4gYW5kIHplcm8tc3RhdHVzIHNjYWZmb2xkaW5nLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBFbnRyeSBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRW50cnlQb2ludH0gU2VtYW50aWMgZW50cnkuXG4gICAqL1xuICBtYWluKG5vZGUpIHtcbiAgICBjb25zdCB0eXBlID0gdGhpcy5maWVsZChub2RlLCBcInR5cGVcIilcbiAgICBjb25zdCBkZWNsYXJhdG9yID0gdGhpcy5maWVsZChub2RlLCBcImRlY2xhcmF0b3JcIilcbiAgICBjb25zdCBib2R5ID0gdGhpcy5maWVsZChub2RlLCBcImJvZHlcIilcblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW3R5cGUsIGRlY2xhcmF0b3IsIGJvZHldKVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmZpZWxkKGRlY2xhcmF0b3IsIFwiZGVjbGFyYXRvclwiKVxuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSB0aGlzLmZpZWxkKGRlY2xhcmF0b3IsIFwicGFyYW1ldGVyc1wiKVxuXG4gICAgdGhpcy5zaGFwZShkZWNsYXJhdG9yLCBbbmFtZSwgcGFyYW1ldGVyc10pXG4gICAgaWYgKHRoaXMudGV4dCh0eXBlKSAhPSBcImludFwiIHx8IHRoaXMudGV4dChuYW1lKSAhPSBcIm1haW5cIikgdGhpcy5mYWlsKG5vZGUsIFwibWFpbiBzaWduYXR1cmVcIilcbiAgICB0aGlzLnNoYXBlKHBhcmFtZXRlcnMsIFtcIihcIiwgXCIpXCJdKVxuICAgIGlmIChib2R5LnR5cGUgIT0gXCJjb21wb3VuZF9zdGF0ZW1lbnRcIikgdGhpcy5mYWlsKGJvZHksIFwiYnJhY2VkIG1haW4gcmVxdWlyZWRcIilcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMoYm9keSlcbiAgICBjb25zdCBzdGF0dXMgPSBwYXJ0cy5hdCgtMilcblxuICAgIGlmICghc3RhdHVzKSB0aGlzLmZhaWwoYm9keSwgXCJtYWluIHN0YXR1c1wiKVxuICAgIHRoaXMuc2hhcGUoYm9keSwgW1wie1wiLCAuLi5wYXJ0cy5zbGljZSgxLCAtMSksIFwifVwiXSlcbiAgICB0aGlzLnNoYXBlKHN0YXR1cywgW1wicmV0dXJuXCIsIFwibnVtYmVyX2xpdGVyYWxcIiwgXCI7XCJdKVxuICAgIGlmICh0aGlzLnRleHQodGhpcy5wYXJ0cyhzdGF0dXMpWzFdKSAhPSBcIjBcIikgdGhpcy5mYWlsKHN0YXR1cywgXCJlbnRyeSBzdGF0dXNcIilcbiAgICByZXR1cm4ge2tpbmQ6IFwiRW50cnlQb2ludFwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgYm9keToge2tpbmQ6IFwiQmxvY2tcIiwgbG9jYXRpb246IHRoaXMubG9jYXRpb24oYm9keSksXG4gICAgICBzdGF0ZW1lbnRzOiB0aGlzLmdlbmVyYXRlZCA/IHRoaXMuZ2VuZXJhdGVkU3RhdGVtZW50cyhib2R5LmNoaWxkcmVuLm1hcCgoe25vZGU6IGNoaWxkfSkgPT4gY2hpbGQpLmZpbHRlcigoY2hpbGQpID0+XG4gICAgICAgIGNoaWxkLnN0YXJ0SW5kZXggPiBib2R5LnN0YXJ0SW5kZXggJiYgY2hpbGQuZW5kSW5kZXggPD0gc3RhdHVzLnN0YXJ0SW5kZXgpKVxuICAgICAgICA6IHBhcnRzLnNsaWNlKDEsIC0yKS5tYXAoKGNoaWxkKSA9PiB0aGlzLnN0YXRlbWVudChjaGlsZCkpfX1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgY29tcGxldGUgdHJhbnNsYXRpb24gdW5pdCBhZnRlciBleGhhdXN0aXZlIHJlY292ZXJ5IHJlamVjdGlvbi5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSByb290IC0gRnJvemVuIHRyYW5zbGF0aW9uIHVuaXQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gVmFsaWRhdGVkIHNlbWFudGljIG1vZHVsZS5cbiAgICovXG4gIG1vZHVsZShyb290KSB7XG4gICAgdGhpcy52YWxpZGF0ZVRyZWUocm9vdClcbiAgICB0aGlzLmdlbmVyYXRlZCA9IHJvb3QuY2hpbGRyZW4uc29tZSgoe25vZGV9KSA9PiBub2RlLnR5cGUgPT0gXCJjb21tZW50XCIgJiYgdGhpcy50ZXh0KG5vZGUpID09IFwiLyogc2VtYW50aWZvbGQ6cHJvZ3JhbTpjcHA6djEgKi9cIilcbiAgICBpZiAocm9vdC50eXBlICE9IFwidHJhbnNsYXRpb25fdW5pdFwiKSB0aGlzLmZhaWwocm9vdCwgXCJ0cmFuc2xhdGlvbiB1bml0IHJlcXVpcmVkXCIpXG4gICAgY29uc3QgcnVudGltZSA9IG5ldyBDcHBSZWFkZXIodGhpcy5maWxlbmFtZSwgY3BwUnVudGltZSlcbiAgICBjb25zdCBleHBlY3RlZCA9IHJ1bnRpbWUuc2lnbmlmaWNhbnQocGFyc2VDcHBDc3QoY3BwUnVudGltZSkucm9vdClcbiAgICBjb25zdCBhY3R1YWwgPSB0aGlzLnNpZ25pZmljYW50KHJvb3QpLmZpbHRlcigobm9kZSkgPT4gIShub2RlLnR5cGUgPT0gXCJjb21tZW50XCIgJiYgdGhpcy50ZXh0KG5vZGUpID09IFwiLyogc2VtYW50aWZvbGQ6cHJvZ3JhbTpjcHA6djEgKi9cIikpXG5cbiAgICBpZiAoYWN0dWFsLmxlbmd0aCA8IGV4cGVjdGVkLmxlbmd0aCkgdGhpcy5mYWlsKHJvb3QsIFwiY29tcGxldGUgQ1BQIHJ1bnRpbWUgcmVxdWlyZWRcIilcbiAgICBleHBlY3RlZC5mb3JFYWNoKChub2RlLCBpbmRleCkgPT4gdGhpcy5jb21wYXJlVHJlZShhY3R1YWxbaW5kZXhdLCBub2RlLCBydW50aW1lKSlcbiAgICBjb25zdCByZW1haW5pbmcgPSBhY3R1YWwuc2xpY2UoZXhwZWN0ZWQubGVuZ3RoKVxuXG4gICAgaWYgKCF0aGlzLmdlbmVyYXRlZCkgZm9yIChjb25zdCBub2RlIG9mIHJlbWFpbmluZykgdGhpcy5yZWplY3RTY2FmZm9sZENvbW1lbnRzKG5vZGUpXG4gICAgY29uc3QgZGVmaW5pdGlvbnMgPSByZW1haW5pbmcuZmlsdGVyKChub2RlKSA9PiBub2RlLnR5cGUgIT0gXCJjb21tZW50XCIgJiYgKCF0aGlzLmdlbmVyYXRlZCB8fCBub2RlLnR5cGUgIT0gXCJkZWNsYXJhdGlvblwiKSlcblxuICAgIGlmIChkZWZpbml0aW9ucy5zb21lKChub2RlKSA9PiBub2RlLnR5cGUgIT0gXCJmdW5jdGlvbl9kZWZpbml0aW9uXCIpKSB0aGlzLmZhaWwocm9vdCwgXCJ0cmFuc2xhdGlvbiB1bml0IG1lbWJlcnNcIilcbiAgICBpZiAoZGVmaW5pdGlvbnMubGVuZ3RoIDwgMikgdGhpcy5mYWlsKHJvb3QsIFwic2VtYW50aWMgZnVuY3Rpb24gYW5kIG1haW4gcmVxdWlyZWRcIilcbiAgICBjb25zdCBtb2R1bGUgPSB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTW9kdWxlXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihyb290KSwgZnVuY3Rpb25zOiBkZWZpbml0aW9ucy5zbGljZSgwLCAtMSkubWFwKChub2RlKSA9PiB0aGlzLmZ1bmN0aW9uKG5vZGUpKSxcbiAgICAgIGVudHJ5UG9pbnQ6IHRoaXMubWFpbihkZWZpbml0aW9uc1tkZWZpbml0aW9ucy5sZW5ndGggLSAxXSl9XG5cbiAgICBpZiAodGhpcy5nZW5lcmF0ZWQpIHZhbGlkYXRlTmF0aXZlR3JhcGgobW9kdWxlLCBcImNwcFwiKVxuICAgIGNvbnN0IHZhbGlkYXRlZCA9IHZhbGlkYXRlUGFyc2VkTW9kdWxlKG1vZHVsZSwgXCJjcHBcIilcblxuICAgIHRoaXMudmFsaWRhdGVQcmludFR5cGVzKHZhbGlkYXRlZClcbiAgICBpZiAodGhpcy5nZW5lcmF0ZWQpIHtcbiAgICAgIHZhbGlkYXRlQmFja2VuZE1vZHVsZSh2YWxpZGF0ZWQsIFwiY3BwXCIpXG4gICAgICBjb25zdCBjYW5vbmljYWwgPSBnZW5lcmF0ZUNwcCh2YWxpZGF0ZWQpXG5cbiAgICAgIGlmICh0eXBlb2YgY2Fub25pY2FsICE9IFwic3RyaW5nXCIpIHRocm93IG5ldyBFcnJvcihcIkNQUCBiYWNrZW5kIHJldHVybmVkIGEgbm9udGV4dCBlbnRyeSBhcnRpZmFjdC5cIilcbiAgICAgIHRoaXMuY29tcGFyZVRyZWUocm9vdCwgcGFyc2VDcHBDc3QoY2Fub25pY2FsKS5yb290LCBuZXcgQ3BwUmVhZGVyKHRoaXMuZmlsZW5hbWUsIGNhbm9uaWNhbCkpXG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0ZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgbmF0aXZlIHByaW50IGhlbHBlciBzZWxlY3Rpb24gYWZ0ZXIgc2VtYW50aWMgc2NhbGFyIHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFJlc29sdmVkIG1vZHVsZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICB2YWxpZGF0ZVByaW50VHlwZXMobW9kdWxlKSB7XG4gICAgY29uc3QgcGxhbm5lciA9IG5ldyBPcmRlcmVkRXhwcmVzc2lvblBsYW5uZXIobW9kdWxlLCBcImNwcFwiKVxuICAgIC8qKlxuICAgICAqIENoZWNrcyBvbmUgbGV4aWNhbCBibG9jayB3aXRoIGl0cyB2aXNpYmxlIHNjYWxhciBiaW5kaW5ncy5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIFNlbWFudGljIGJsb2NrLlxuICAgICAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZT59IGluaGVyaXRlZCAtIFZpc2libGUgYmluZGluZ3MuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgY29uc3QgdmlzaXQgPSAoYmxvY2ssIGluaGVyaXRlZCkgPT4ge1xuICAgICAgY29uc3QgYmluZGluZ3MgPSBuZXcgTWFwKGluaGVyaXRlZClcblxuICAgICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIGJpbmRpbmdzLnNldChzdGF0ZW1lbnQubmFtZSwgc3RhdGVtZW50LnR5cGUubmFtZSlcbiAgICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgICAgICAgIGNvbnN0IGV4cGVjdGVkID0gdGhpcy5wcmludFR5cGVzLmdldChzdGF0ZW1lbnQpXG5cbiAgICAgICAgICBpZiAoIWV4cGVjdGVkKSB0aHJvdyBuZXcgRXJyb3IoXCJDUFAgcHJpbnQgc3RhdGVtZW50IGxvc3QgaXRzIHBhcnNlciBoZWxwZXIgaWRlbnRpdHkuXCIpXG4gICAgICAgICAgaWYgKHBsYW5uZXIudHlwZShzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgYmluZGluZ3MpICE9IGV4cGVjdGVkLnR5cGUpIHRoaXMuZmFpbChleHBlY3RlZC5ub2RlLCBcInByaW50IGhlbHBlciBzY2FsYXIgbWlzbWF0Y2hcIilcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiKSB7XG4gICAgICAgICAgdmlzaXQoc3RhdGVtZW50LmNvbnNlcXVlbnQsIGJpbmRpbmdzKVxuICAgICAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB2aXNpdChzdGF0ZW1lbnQuYWx0ZXJuYXRlLCBiaW5kaW5ncylcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykgdmlzaXQoZGVjbGFyYXRpb24uYm9keSwgbmV3IE1hcChkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlci50eXBlLm5hbWVdKSkpXG4gICAgdmlzaXQobW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgbmV3IE1hcCgpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlamVjdHMgcHJvZmlsZS1sb29raW5nIGNvbW1lbnRzIG91dHNpZGUgYSBjb21wbGV0ZSBjYW5vbmljYWwgZ2VuZXJhdGVkIHByb2dyYW0uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEN1cnJlbnQgbm9kZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWplY3RTY2FmZm9sZENvbW1lbnRzKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlID09IFwiY29tbWVudFwiICYmIC9zZW1hbnRpZm9sZDp8QHNlbWFudGlmb2xkL3UudGVzdCh0aGlzLnRleHQobm9kZSkpKSB0aGlzLmZhaWwobm9kZSwgXCJ1bnJlY29nbml6ZWQgc2NhZmZvbGQgY29tbWVudFwiKVxuICAgIGZvciAoY29uc3Qge25vZGU6IGNoaWxkfSBvZiBub2RlLmNoaWxkcmVuKSB0aGlzLnJlamVjdFNjYWZmb2xkQ29tbWVudHMoY2hpbGQpXG4gIH1cblxuICAvKipcbiAgICogUmV0YWlucyBldmVyeSBzY2FmZm9sZCBjb21tZW50IGFuZCBzdHJ1Y3R1cmFsIGVkZ2UsIGlnbm9yaW5nIG9ubHkgb3JkaW5hcnkgY29tbWVudHMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIENTVCBwYXJlbnQuXG4gICAqIEByZXR1cm5zIHtDc3ROb2RlW119IENvbXBsZXRlIHNpZ25pZmljYW50IGNoaWxkIGxpc3QuXG4gICAqL1xuICBzaWduaWZpY2FudChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4ubWFwKCh7bm9kZTogY2hpbGR9KSA9PiBjaGlsZCkuZmlsdGVyKChjaGlsZCkgPT5cbiAgICAgIGNoaWxkLnR5cGUgIT0gXCJjb21tZW50XCIgfHwgL3NlbWFudGlmb2xkOnxAc2VtYW50aWZvbGQvdS50ZXN0KHRoaXMudGV4dChjaGlsZCkpKVxuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIGV2ZXJ5IHRva2VuLCBmaWVsZCwgdHlwZSwgdXNlLCBvcmRlcmluZyBlZGdlIGFuZCBjb25zdW1lciBhZ2FpbnN0IHRoZSBjYW5vbmljYWwgcGxhbi5cbiAgICogVGhpcyBjaGVja3MgdGhlIG9yaWdpbmFsIENTVDsgaXQgbmV2ZXIgcmVjb3ZlcnMgbWVhbmluZyBmcm9tIGdlbmVyYXRlZCBzb3VyY2UgdGV4dC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBhY3R1YWwgLSBPcmlnaW5hbCB0cmVlIG5vZGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gZXhwZWN0ZWQgLSBDYW5vbmljYWwgdHJlZSBub2RlIGZvciB0aGUgcmVjb25zdHJ1Y3RlZCBzZW1hbnRpY3MuXG4gICAqIEBwYXJhbSB7Q3BwUmVhZGVyfSBjYW5vbmljYWwgLSBDYW5vbmljYWwgdG9rZW4gcmVhZGVyLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNvbXBhcmVUcmVlKGFjdHVhbCwgZXhwZWN0ZWQsIGNhbm9uaWNhbCkge1xuICAgIGlmIChhY3R1YWwudHlwZSAhPSBleHBlY3RlZC50eXBlIHx8IGFjdHVhbC5uYW1lZCAhPSBleHBlY3RlZC5uYW1lZCB8fCBhY3R1YWwuZXh0cmEgIT0gZXhwZWN0ZWQuZXh0cmEpIHRoaXMuZmFpbChhY3R1YWwsIFwiZ2VuZXJhdGVkIHNjYWZmb2xkIG5vZGUgc2hhcGVcIilcbiAgICBjb25zdCBsZWZ0ID0gdGhpcy5zaWduaWZpY2FudChhY3R1YWwpXG4gICAgY29uc3QgcmlnaHQgPSBjYW5vbmljYWwuc2lnbmlmaWNhbnQoZXhwZWN0ZWQpXG5cbiAgICBpZiAobGVmdC5sZW5ndGggIT0gcmlnaHQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsLCBcImdlbmVyYXRlZCBzY2FmZm9sZCBjaGlsZCBjb3VudFwiKVxuICAgIGlmICghbGVmdC5sZW5ndGggJiYgdGhpcy50ZXh0KGFjdHVhbCkgIT0gY2Fub25pY2FsLnRleHQoZXhwZWN0ZWQpKSB0aGlzLmZhaWwoYWN0dWFsLCBcImdlbmVyYXRlZCBzY2FmZm9sZCB0b2tlbiwgdHlwZSwgb3JkZXIgb3IgY29uc3VtZXJcIilcbiAgICBsZWZ0LmZvckVhY2goKGNoaWxkLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGFjdHVhbC5jaGlsZHJlbi5maW5kKChlZGdlKSA9PiBlZGdlLm5vZGUgPT09IGNoaWxkKT8uZmllbGQgIT0gZXhwZWN0ZWQuY2hpbGRyZW4uZmluZCgoZWRnZSkgPT4gZWRnZS5ub2RlID09PSByaWdodFtpbmRleF0pPy5maWVsZCkgdGhpcy5mYWlsKGNoaWxkLCBcImdlbmVyYXRlZCBzY2FmZm9sZCBmaWVsZFwiKVxuICAgICAgdGhpcy5jb21wYXJlVHJlZShjaGlsZCwgcmlnaHRbaW5kZXhdLCBjYW5vbmljYWwpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvZ25pemVzIHRoZSBzaGFwZSBvZiBhbiBpbmVydCBnZW5lcmF0ZWQgdW51c2VkLWJpbmRpbmcgY2FzdDsgY2Fub25pY2FsIGNvbXBhcmlzb24gY2hlY2tzIGl0cyBleGFjdCB0YXJnZXQgYW5kIHBsYWNlbWVudC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gQ2FuZGlkYXRlIHN0YXRlbWVudC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhpcyBpcyBhIGRpc2NhcmQtc2hhcGVkIGNhbmRpZGF0ZS5cbiAgICovXG4gIGRpc2NhcmQobm9kZSkge1xuICAgIHJldHVybiBub2RlLnR5cGUgPT0gXCJleHByZXNzaW9uX3N0YXRlbWVudFwiICYmIHRoaXMucGFydHMobm9kZSlbMF0/LnR5cGUgPT0gXCJjYXN0X2V4cHJlc3Npb25cIlxuICB9XG5cbiAgLyoqXG4gICAqIFJlY29uc3RydWN0cyBwYWlyZWQgc3RhdGVtZW50IHJlZ2lvbnMgYmVmb3JlIG1hbmRhdG9yeSB3aG9sZS1DU1QgY2Fub25pY2FsIHZlcmlmaWNhdGlvbi5cbiAgICogQHBhcmFtIHtDc3ROb2RlW119IGNoaWxkcmVuIC0gT3JkZXJlZCBibG9jayBjaGlsZHJlbiB3aXRob3V0IGJyYWNlcyBvciBtYWluIGNsZWFudXAuXG4gICAqIEByZXR1cm5zIHtTdGF0ZW1lbnRbXX0gQ2FuZGlkYXRlIHNlbWFudGljIHN0YXRlbWVudHMuXG4gICAqL1xuICBnZW5lcmF0ZWRTdGF0ZW1lbnRzKGNoaWxkcmVuKSB7XG4gICAgY29uc3Qgbm9kZXMgPSBjaGlsZHJlbi5maWx0ZXIoKG5vZGUpID0+IG5vZGUudHlwZSAhPSBcImNvbW1lbnRcIiB8fCAvc2VtYW50aWZvbGQ6fEBzZW1hbnRpZm9sZC91LnRlc3QodGhpcy50ZXh0KG5vZGUpKSlcbiAgICAvKiogQHR5cGUge1N0YXRlbWVudFtdfSAqL1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBbXVxuICAgIGxldCBjdXJzb3IgPSAwXG5cbiAgICB3aGlsZSAoY3Vyc29yIDwgbm9kZXMubGVuZ3RoICYmIHRoaXMuZGlzY2FyZChub2Rlc1tjdXJzb3JdKSkgY3Vyc29yKytcbiAgICB3aGlsZSAoY3Vyc29yIDwgbm9kZXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBiZWdpbiA9IG5vZGVzW2N1cnNvcisrXVxuICAgICAgY29uc3QgbWF0Y2ggPSBiZWdpbi50eXBlID09IFwiY29tbWVudFwiICYmIC9eXFwvXFwqIHNlbWFudGlmb2xkOm9yZGVyZWQtZXhwcmVzc2lvbjpjcHA6djEgYmVnaW4gKFswLTldezZ9KSAoWzAtOWEtZl17NjR9KSBcXCpcXC8kL3UuZXhlYyh0aGlzLnRleHQoYmVnaW4pKVxuXG4gICAgICBpZiAoIW1hdGNoKSB0aGlzLmZhaWwoYmVnaW4sIFwiY29tcGxldGUgb3JkZXJlZCBzdGF0ZW1lbnQgcmVnaW9uIHJlcXVpcmVkXCIpXG4gICAgICBjb25zdCBvdXRlciA9IHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnNcbiAgICAgIGNvbnN0IG91dGVyTmFtZXMgPSB0aGlzLnRlbXBvcmFyeU5hbWVzXG5cbiAgICAgIHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnMgPSBuZXcgTWFwKClcbiAgICAgIHRoaXMudGVtcG9yYXJ5TmFtZXMgPSBuZXcgU2V0KClcbiAgICAgIHdoaWxlIChjdXJzb3IgPCBub2Rlcy5sZW5ndGggJiYgdGhpcy50ZW1wb3JhcnlEZWNsYXJhdGlvbihub2Rlc1tjdXJzb3JdKSkgY3Vyc29yID0gdGhpcy5yZWFkVGVtcG9yYXJ5KG5vZGVzLCBjdXJzb3IpXG4gICAgICBjb25zdCBjb25zdW1lciA9IG5vZGVzW2N1cnNvcisrXVxuXG4gICAgICBpZiAoIWNvbnN1bWVyKSB0aGlzLmZhaWwoYmVnaW4sIFwibWlzc2luZyBvcmRlcmVkIGNvbnN1bWVyXCIpXG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB0aGlzLnN0YXRlbWVudChjb25zdW1lcilcblxuICAgICAgaWYgKHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnMuc2l6ZSAhPSAwKSB0aGlzLmZhaWwoY29uc3VtZXIsIFwidW5jb25zdW1lZCBvcmRlcmVkIHRlbXBvcmFyeVwiKVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiICYmIG5vZGVzW2N1cnNvcl0gJiYgdGhpcy5kaXNjYXJkKG5vZGVzW2N1cnNvcl0pKSBjdXJzb3IrK1xuICAgICAgY29uc3QgZW5kID0gbm9kZXNbY3Vyc29yKytdXG5cbiAgICAgIGlmICghZW5kIHx8IGVuZC50eXBlICE9IFwiY29tbWVudFwiIHx8IHRoaXMudGV4dChlbmQpICE9IGAvKiBzZW1hbnRpZm9sZDpvcmRlcmVkLWV4cHJlc3Npb246Y3BwOnYxIGVuZCAke21hdGNoWzFdfSAke21hdGNoWzJdfSAqL2ApIHRoaXMuZmFpbChlbmQgPz8gYmVnaW4sIFwib3JkZXJlZCBtYXJrZXIgcGFpclwiKVxuICAgICAgdGhpcy50ZW1wb3JhcnlFeHByZXNzaW9ucyA9IG91dGVyXG4gICAgICB0aGlzLnRlbXBvcmFyeU5hbWVzID0gb3V0ZXJOYW1lc1xuICAgICAgc3RhdGVtZW50cy5wdXNoKHN0YXRlbWVudClcbiAgICB9XG4gICAgcmV0dXJuIHN0YXRlbWVudHNcbiAgfVxuXG4gIC8qKlxuICAgKiBJZGVudGlmaWVzIG9ubHkgYSBkZWNsYXJhdGlvbiBhdCB0aGUgY3VycmVudCByZWdpb24gbGV2ZWwsIHdpdGhvdXQgZGVzY2VuZGFudCBzZWFyY2hpbmcuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIENhbmRpZGF0ZSBub2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZGlyZWN0IGluaXRpYWxpemVkIG5hbWUgdXNlcyB0aGUgcmVzZXJ2ZWQgcHJlZml4LlxuICAgKi9cbiAgdGVtcG9yYXJ5RGVjbGFyYXRpb24obm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJkZWNsYXJhdGlvblwiKSByZXR1cm4gZmFsc2VcbiAgICBjb25zdCBkZWNsYXJhdG9yID0gbm9kZS5jaGlsZHJlbi5maW5kKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBcImRlY2xhcmF0b3JcIik/Lm5vZGVcbiAgICBjb25zdCBuYW1lID0gZGVjbGFyYXRvcj8uY2hpbGRyZW4uZmluZCgoe2ZpZWxkfSkgPT4gZmllbGQgPT0gXCJkZWNsYXJhdG9yXCIpPy5ub2RlXG5cbiAgICByZXR1cm4gbmFtZT8udHlwZSA9PSBcImlkZW50aWZpZXJcIiAmJiB0aGlzLnRleHQobmFtZSkuc3RhcnRzV2l0aChcInNlbWFudGlmb2xkX29yZGVyZWRfXCIpXG4gIH1cblxuICAvKipcbiAgICogRXhwYW5kcyBvbmUgY2FuZGlkYXRlIHRlbXBvcmFyeSwgaW5jbHVkaW5nIGl0cyBjb25kaXRpb25hbCBSSFMsIHJldGFpbmluZyBvcmlnaW5hbCBvcGVyYXRpb24gdG9rZW5zLlxuICAgKiBAcGFyYW0ge0NzdE5vZGVbXX0gbm9kZXMgLSBDdXJyZW50IGxleGljYWwgc2VxdWVuY2UuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjdXJzb3IgLSBEZWNsYXJhdGlvbiBwb3NpdGlvbi5cbiAgICogQHJldHVybnMge251bWJlcn0gTmV4dCB1bmNvbnN1bWVkIHBvc2l0aW9uLlxuICAgKi9cbiAgcmVhZFRlbXBvcmFyeShub2RlcywgY3Vyc29yKSB7XG4gICAgY29uc3Qgbm9kZSA9IG5vZGVzW2N1cnNvcisrXVxuICAgIGNvbnN0IGRlY2xhcmF0b3IgPSB0aGlzLmZpZWxkKG5vZGUsIFwiZGVjbGFyYXRvclwiKVxuICAgIGNvbnN0IG5hbWVOb2RlID0gdGhpcy5maWVsZChkZWNsYXJhdG9yLCBcImRlY2xhcmF0b3JcIilcbiAgICBjb25zdCBuYW1lID0gdGhpcy50ZXh0KG5hbWVOb2RlKVxuICAgIGNvbnN0IHR5cGUgPSB0aGlzLmZpZWxkKG5vZGUsIFwidHlwZVwiKVxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5maWVsZChkZWNsYXJhdG9yLCBcInZhbHVlXCIpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFt0eXBlLCBkZWNsYXJhdG9yLCBcIjtcIl0pXG4gICAgdGhpcy5zaGFwZShkZWNsYXJhdG9yLCBbbmFtZU5vZGUsIFwiPVwiLCB2YWx1ZV0pXG4gICAgdGhpcy50eXBlKHR5cGUpXG4gICAgaWYgKCEvXnNlbWFudGlmb2xkX29yZGVyZWRfWzAtOV17Nn0kL3UudGVzdChuYW1lKSB8fCB0aGlzLnRlbXBvcmFyeU5hbWVzPy5oYXMobmFtZSkpIHRoaXMuZmFpbChuYW1lTm9kZSwgXCJvcmRlcmVkIHRlbXBvcmFyeSBkZWNsYXJhdGlvblwiKVxuICAgIHRoaXMudGVtcG9yYXJ5TmFtZXM/LmFkZChuYW1lKVxuICAgIGxldCBleHByZXNzaW9uID0gdGhpcy5leHByZXNzaW9uKHZhbHVlKVxuICAgIGNvbnN0IGJyYW5jaCA9IG5vZGVzW2N1cnNvcl1cblxuICAgIGlmIChicmFuY2g/LnR5cGUgPT0gXCJpZl9zdGF0ZW1lbnRcIiAmJiBbXCJpZGVudGlmaWVyXCIsIFwidHJ1ZVwiLCBcImZhbHNlXCJdLmluY2x1ZGVzKHZhbHVlLnR5cGUpKSB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSB0aGlzLmZpZWxkKGJyYW5jaCwgXCJjb25kaXRpb25cIilcbiAgICAgIGNvbnN0IGJvZHkgPSB0aGlzLmZpZWxkKGJyYW5jaCwgXCJjb25zZXF1ZW5jZVwiKVxuXG4gICAgICB0aGlzLnNoYXBlKGJyYW5jaCwgW1wiaWZcIiwgY29uZGl0aW9uLCBib2R5XSlcbiAgICAgIHRoaXMuc2hhcGUoY29uZGl0aW9uLCBbXCIoXCIsIHRoaXMucGFydHMoY29uZGl0aW9uKVsxXSwgXCIpXCJdKVxuICAgICAgY29uc3QgdGVzdCA9IHRoaXMucGFydHMoY29uZGl0aW9uKVsxXVxuICAgICAgY29uc3QgaXNPciA9IHRlc3QudHlwZSA9PSBcInVuYXJ5X2V4cHJlc3Npb25cIlxuICAgICAgY29uc3QgdGFyZ2V0ID0gaXNPciA/IHRoaXMuZmllbGQodGVzdCwgXCJhcmd1bWVudFwiKSA6IHRlc3RcblxuICAgICAgaWYgKHRhcmdldC50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8IHRoaXMudGV4dCh0YXJnZXQpICE9IG5hbWUpIHRoaXMuZmFpbCh0YXJnZXQsIFwic2hvcnQtY2lyY3VpdCB0ZW1wb3JhcnkgdGVzdFwiKVxuICAgICAgaWYgKGlzT3IpIHRoaXMuc2hhcGUodGVzdCwgW1wiIVwiLCB0YXJnZXRdKVxuICAgICAgaWYgKGJvZHkudHlwZSAhPSBcImNvbXBvdW5kX3N0YXRlbWVudFwiKSB0aGlzLmZhaWwoYm9keSwgXCJzaG9ydC1jaXJjdWl0IGJsb2NrXCIpXG4gICAgICBjb25zdCBpbnNpZGUgPSB0aGlzLnNpZ25pZmljYW50KGJvZHkpLnNsaWNlKDEsIC0xKVxuICAgICAgbGV0IG9mZnNldCA9IDBcblxuICAgICAgd2hpbGUgKG9mZnNldCA8IGluc2lkZS5sZW5ndGggJiYgdGhpcy50ZW1wb3JhcnlEZWNsYXJhdGlvbihpbnNpZGVbb2Zmc2V0XSkpIG9mZnNldCA9IHRoaXMucmVhZFRlbXBvcmFyeShpbnNpZGUsIG9mZnNldClcbiAgICAgIGlmIChvZmZzZXQgIT0gaW5zaWRlLmxlbmd0aCAtIDEpIHRoaXMuZmFpbChib2R5LCBcInNob3J0LWNpcmN1aXQgZmluYWwgd3JpdGVcIilcbiAgICAgIGNvbnN0IGFzc2lnbm1lbnQgPSBpbnNpZGVbb2Zmc2V0XVxuXG4gICAgICB0aGlzLnNoYXBlKGFzc2lnbm1lbnQsIFtcImFzc2lnbm1lbnRfZXhwcmVzc2lvblwiLCBcIjtcIl0pXG4gICAgICBjb25zdCBhc3NpZ25lZCA9IHRoaXMucGFydHMoYXNzaWdubWVudClbMF1cbiAgICAgIGNvbnN0IGxlZnQgPSB0aGlzLmZpZWxkKGFzc2lnbmVkLCBcImxlZnRcIilcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChhc3NpZ25lZCwgXCJyaWdodFwiKVxuXG4gICAgICB0aGlzLnNoYXBlKGFzc2lnbmVkLCBbbGVmdCwgXCI9XCIsIHJpZ2h0XSlcbiAgICAgIGlmIChsZWZ0LnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KGxlZnQpICE9IG5hbWUpIHRoaXMuZmFpbChsZWZ0LCBcInNob3J0LWNpcmN1aXQgcmVzdWx0IHdyaXRlXCIpXG4gICAgICB0aGlzLnNoYXBlKHJpZ2h0LCBbXCIoXCIsIFwiYmluYXJ5X2V4cHJlc3Npb25cIiwgXCIpXCJdKVxuICAgICAgY29uc3QgYmluYXJ5ID0gdGhpcy5wYXJ0cyhyaWdodClbMV1cbiAgICAgIGNvbnN0IHJlcGVhdGVkID0gdGhpcy5maWVsZChiaW5hcnksIFwibGVmdFwiKVxuICAgICAgY29uc3Qgb3BlcmFuZCA9IHRoaXMuZmllbGQoYmluYXJ5LCBcInJpZ2h0XCIpXG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQoYmluYXJ5LCBcIm9wZXJhdG9yXCIpXG5cbiAgICAgIHRoaXMuc2hhcGUoYmluYXJ5LCBbcmVwZWF0ZWQsIGlzT3IgPyBcInx8XCIgOiBcIiYmXCIsIG9wZXJhbmRdKVxuICAgICAgaWYgKHJlcGVhdGVkLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KHJlcGVhdGVkKSAhPSBuYW1lKSB0aGlzLmZhaWwocmVwZWF0ZWQsIFwic2hvcnQtY2lyY3VpdCBjb25zdW1lZCB2YWx1ZVwiKVxuICAgICAgZXhwcmVzc2lvbiA9IHRoaXMuYmluYXJ5KG5vZGUsIGlzT3IgPyBcIk9yXCIgOiBcIkFuZFwiLCBleHByZXNzaW9uLCB0aGlzLmV4cHJlc3Npb24ob3BlcmFuZCksIG9wZXJhdG9yKVxuICAgICAgY3Vyc29yKytcbiAgICB9XG4gICAgdGhpcy50ZW1wb3JhcnlFeHByZXNzaW9ucz8uc2V0KG5hbWUsIGV4cHJlc3Npb24pXG4gICAgcmV0dXJuIGN1cnNvclxuICB9XG59XG5cbi8qKlxuICogUGFyc2VzIG9ubHkgdGhlIGZyb3plbiBsZWdhY3kgQ1NULCB3aXRoIG5vIHNvdXJjZS10ZXh0IHJlY292ZXJ5IHBhdGguXG4gKiBAcGFyYW0ge3tmaWxlbmFtZTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZ319IGlucHV0IC0gRXhhY3QgY2FsbGVyIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gUGFyc2VkIEMrKyBzZW1hbnRpY3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNwcCh7ZmlsZW5hbWUsIHNvdXJjZX0pIHtcbiAgaWYgKCFoYXNPbmx5VW5pY29kZVNjYWxhcnMoc291cmNlKSkge1xuICAgIGNvbnN0IGNvb3JkaW5hdGVzID0gY3JlYXRlQ29vcmRpbmF0ZUluZGV4KHNvdXJjZSlcbiAgICBjb25zdCBvZmZzZXQgPSBzb3VyY2Uuc2VhcmNoKC9bXFx1RDgwMC1cXHVEQkZGXSg/IVtcXHVEQzAwLVxcdURGRkZdKXwoPzwhW1xcdUQ4MDAtXFx1REJGRl0pW1xcdURDMDAtXFx1REZGRl0vdSlcblxuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiUEFSU0VfRVJST1JcIiwgbGFuZ3VhZ2U6IFwiY3BwXCIsIG1lc3NhZ2U6IFwiQ1BQIHNvdXJjZSBjb250YWlucyBhIGxvbmUgVVRGLTE2IHN1cnJvZ2F0ZS5cIixcbiAgICAgIGxvY2F0aW9uOiB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0KSwgZW5kOiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0ICsgMSl9fSlcbiAgfVxuICBpZiAoc291cmNlLmxlbmd0aCA+IG1heGltdW1DcHBTb3VyY2VMZW5ndGgpIHtcbiAgICBjb25zdCBjb29yZGluYXRlcyA9IGNyZWF0ZUNvb3JkaW5hdGVJbmRleChzb3VyY2UpXG5cbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJjcHBcIiwgXCJzb3VyY2UgZXhjZWVkcyB0aGUgZnJvemVuIENQUCBwYXJzZXIncyAzMjc2NyBVVEYtMTYgaW5wdXQgbGltaXRcIiwge1xuICAgICAgZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgMCksIGVuZDogaW5kZXhlZFBvaW50QXQoY29vcmRpbmF0ZXMsIHNvdXJjZS5sZW5ndGgpXG4gICAgfSlcbiAgfVxuICBsZXQgc25hcHNob3RcblxuICB0cnkge1xuICAgIHNuYXBzaG90ID0gcGFyc2VDcHBDc3Qoc291cmNlKVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGNvb3JkaW5hdGVzID0gY3JlYXRlQ29vcmRpbmF0ZUluZGV4KHNvdXJjZSlcblxuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiUEFSU0VfRVJST1JcIiwgbGFuZ3VhZ2U6IFwiY3BwXCIsXG4gICAgICBjYXVzZTogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogdW5kZWZpbmVkLCBtZXNzYWdlOiBcIlRoZSBxdWFsaWZpZWQgQ1BQIHBhcnNlciBjb3VsZCBub3QgcHJvZHVjZSBhIGNvbXBsZXRlIENTVC5cIixcbiAgICAgIGxvY2F0aW9uOiB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgMCksIGVuZDogaW5kZXhlZFBvaW50QXQoY29vcmRpbmF0ZXMsIHNvdXJjZS5sZW5ndGgpfX0pXG4gIH1cbiAgY29uc3QgcmVhZGVyID0gbmV3IENwcFJlYWRlcihmaWxlbmFtZSwgc291cmNlKVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlYWRlci5tb2R1bGUoc25hcHNob3Qucm9vdClcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAocmVhZGVyLmdlbmVyYXRlZCAmJiBlcnJvciBpbnN0YW5jZW9mIFNlbWFudGlmb2xkRGlhZ25vc3RpYyAmJiBlcnJvci5sYW5ndWFnZSA9PSBcImNwcFwiICYmXG4gICAgICBlcnJvci5jb2RlICE9IFwiUEFSU0VfRVJST1JcIiAmJiBlcnJvci5jb2RlICE9IFwiVU5TVVBQT1JURURfU1lOVEFYXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcImNwcFwiLCBgaW52YWxpZCBnZW5lcmF0ZWQgb3JkZXJlZCBzY2FmZm9sZDogJHtlcnJvci5jb2RlfWAsIGVycm9yLmxvY2F0aW9uID8/IHJlYWRlci5sb2NhdGlvbihzbmFwc2hvdC5yb290KSlcbiAgICB9XG4gICAgdGhyb3cgZXJyb3JcbiAgfVxufVxuIl19
|