semantifold 0.3.0 → 0.4.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 +58 -15
- package/build/index.d.ts +48 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +154 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +23 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +136 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +81 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1308 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2158 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +235 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +468 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +167 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +2952 -202
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +688 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/architecture.md +45 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +231 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +15 -7
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +366 -4
- package/docs/webassembly.md +52 -0
- package/index.js +63 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +160 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +141 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1407 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2304 -124
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +520 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +172 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +765 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -0,0 +1,746 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { unsupportedCapability } from "../diagnostic.js";
|
|
3
|
+
import { isTask034ResourceProbe } from "../semantic/capabilities.js";
|
|
4
|
+
const adoptedTargets = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
5
|
+
const task037Authorities = new Set([
|
|
6
|
+
"semantifold.output", "semantifold.resource", "semantifold.socket-client", "semantifold.text-stream"
|
|
7
|
+
]);
|
|
8
|
+
const protectedSupportNames = new Set([
|
|
9
|
+
"ProbeOperationFailure", "ProbeAcquireFailure", "ProbeReadFailure", "ProbeCloseFailure", "ProbeResourceClosed", "ProbeResource",
|
|
10
|
+
"probeEffect", "probeAcquire", "probeRead", "probeClose", "probeTrace"
|
|
11
|
+
]);
|
|
12
|
+
/** @typedef {{expression: import("../semantic/types.js").Expression, path: string}} ExpressionPath */
|
|
13
|
+
/** @typedef {{detail: string, location: import("../semantic/types.js").SourceLocation}} ExcludedEffect */
|
|
14
|
+
/**
|
|
15
|
+
* Validates Task 034 target support before a SourceWriter is allocated.
|
|
16
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate module.
|
|
17
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Requested target.
|
|
18
|
+
* @param {{usedOperations?: readonly string[]}} [options] - Program-wide used canonical
|
|
19
|
+
* operations for a linked stdlib provider; restricts the reserved support surface to the
|
|
20
|
+
* operations actually materialized in the provider artifact.
|
|
21
|
+
* @returns {void}
|
|
22
|
+
*/
|
|
23
|
+
export function preflightEffectCapabilities(module, language, options = {}) {
|
|
24
|
+
const capabilities = module?.capabilities;
|
|
25
|
+
if (capabilities === undefined) {
|
|
26
|
+
const unauthorized = findTask034Node(module);
|
|
27
|
+
if (unauthorized) {
|
|
28
|
+
unsupportedCapability(language, "MISSING_CAPABILITY_AUTHORITY: Task 034 IR requires its compiler authority graph",
|
|
29
|
+
/** @type {import("../semantic/types.js").SourceLocation | undefined} */ (Reflect.get(unauthorized, "location") ?? module?.location));
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!Array.isArray(capabilities) || capabilities.length == 0) {
|
|
34
|
+
unsupportedCapability(language, "malformed or empty Task 034 capability graph", module?.location);
|
|
35
|
+
}
|
|
36
|
+
if (!adoptedTargets.has(language)) {
|
|
37
|
+
unsupportedCapability(language, "Task 034 effectful capabilities and owned resources", module.location);
|
|
38
|
+
}
|
|
39
|
+
const task037 = language == "php" && capabilities.every((capability) => task037Authorities.has(capability.authorityId));
|
|
40
|
+
if (!isTask034ResourceProbe(capabilities) && !task037) {
|
|
41
|
+
unsupportedCapability(language, "unbound Task 034 capability authority", module.location);
|
|
42
|
+
}
|
|
43
|
+
if (!Array.isArray(module.functions) || !module.entryPoint || typeof module.entryPoint != "object" ||
|
|
44
|
+
!module.entryPoint.body || !Array.isArray(module.entryPoint.body.statements) ||
|
|
45
|
+
[module.records, module.classes, module.errors].some((declarations) => declarations !== undefined && !Array.isArray(declarations))) {
|
|
46
|
+
unsupportedCapability(language, "malformed Task 034 semantic module", module.location);
|
|
47
|
+
}
|
|
48
|
+
const collision = moduleNeedsEffectSupport(module) ? findSupportCollision(module, language, options.usedOperations) : undefined;
|
|
49
|
+
if (collision)
|
|
50
|
+
unsupportedCapability(language, `protected Task 034 support name '${collision.name}'`, collision.location);
|
|
51
|
+
const excluded = findExcludedEffectContext(module);
|
|
52
|
+
if (excluded)
|
|
53
|
+
unsupportedCapability(language, excluded.detail, excluded.location);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Finds compiler-authorized Task 034 IR that has been detached from its authority graph.
|
|
57
|
+
* @param {unknown} value - Candidate semantic graph.
|
|
58
|
+
* @param {Set<object>} [seen] - Cycle protection.
|
|
59
|
+
* @returns {object | undefined} First unauthorized Task 034 node.
|
|
60
|
+
*/
|
|
61
|
+
function findTask034Node(value, seen = new Set()) {
|
|
62
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
63
|
+
return undefined;
|
|
64
|
+
seen.add(value);
|
|
65
|
+
if (!Array.isArray(value)) {
|
|
66
|
+
const kind = Reflect.get(value, "kind");
|
|
67
|
+
if (["EffectCallExpression", "OwnedBorrowExpression", "OwnedMoveExpression", "OwnedReferenceType", "OwnedResourceType"].includes(String(kind)) ||
|
|
68
|
+
kind == "ErrorType" && /^capability:[0-9]+\/failure:[0-9]+$/u.test(String(Reflect.get(value, "declarationId"))))
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
for (const [key, child] of Object.entries(value)) {
|
|
72
|
+
if (["location", "sourceProvenance"].includes(key))
|
|
73
|
+
continue;
|
|
74
|
+
const found = findTask034Node(child, seen);
|
|
75
|
+
if (found)
|
|
76
|
+
return found;
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Finds one user declaration that would collide with the protected support surface.
|
|
82
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Validated semantic graph.
|
|
83
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
84
|
+
* @param {readonly string[]} [usedOperations] - Linked provider operations; omitted for the full inlined surface.
|
|
85
|
+
* @returns {{name: string, location: import("../semantic/types.js").SourceLocation} | undefined} First collision.
|
|
86
|
+
*/
|
|
87
|
+
function findSupportCollision(module, language, usedOperations) {
|
|
88
|
+
const reserved = new Set();
|
|
89
|
+
if (usedOperations === undefined) {
|
|
90
|
+
for (const name of protectedSupportNames)
|
|
91
|
+
reserved.add(supportNameKey(name, language));
|
|
92
|
+
if (language == "javascript" || language == "typescript") {
|
|
93
|
+
reserved.add("__semantifoldTask034Fs");
|
|
94
|
+
reserved.add("__semantifoldTask034Trace");
|
|
95
|
+
}
|
|
96
|
+
else if (language == "php")
|
|
97
|
+
reserved.add("__semantifold_task034_trace");
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const used = new Set(usedOperations);
|
|
101
|
+
for (const name of used)
|
|
102
|
+
reserved.add(supportNameKey(name, language));
|
|
103
|
+
if (used.has("probeEffect"))
|
|
104
|
+
reserved.add(supportNameKey("ProbeOperationFailure", language));
|
|
105
|
+
if (used.has("probeAcquire"))
|
|
106
|
+
reserved.add(supportNameKey("ProbeAcquireFailure", language));
|
|
107
|
+
if (used.has("probeRead"))
|
|
108
|
+
reserved.add(supportNameKey("ProbeReadFailure", language));
|
|
109
|
+
if (used.has("probeClose"))
|
|
110
|
+
reserved.add(supportNameKey("ProbeCloseFailure", language));
|
|
111
|
+
if (used.has("probeRead") || used.has("probeClose"))
|
|
112
|
+
reserved.add(supportNameKey("ProbeResourceClosed", language));
|
|
113
|
+
if (used.has("probeAcquire") || used.has("probeRead") || used.has("probeClose")) {
|
|
114
|
+
reserved.add(supportNameKey("ProbeResource", language));
|
|
115
|
+
}
|
|
116
|
+
if (used.size > 0) {
|
|
117
|
+
if (language == "javascript" || language == "typescript") {
|
|
118
|
+
reserved.add("__semantifoldTask034Trace");
|
|
119
|
+
if (used.has("probeAcquire"))
|
|
120
|
+
reserved.add("__semantifoldTask034Fs");
|
|
121
|
+
}
|
|
122
|
+
else if (language == "php")
|
|
123
|
+
reserved.add("__semantifold_task034_trace");
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const declarations = [...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions];
|
|
127
|
+
for (const declaration of declarations) {
|
|
128
|
+
if (!declaration || typeof declaration != "object")
|
|
129
|
+
continue;
|
|
130
|
+
if (reserved.has(supportNameKey(declaration.name, language)))
|
|
131
|
+
return { location: declaration.location, name: declaration.name };
|
|
132
|
+
}
|
|
133
|
+
if (language == "javascript" || language == "typescript" || language == "php") {
|
|
134
|
+
for (const statement of module.entryPoint.body.statements) {
|
|
135
|
+
if (!statement || typeof statement != "object")
|
|
136
|
+
continue;
|
|
137
|
+
if (statement.kind == "LocalDeclaration" && reserved.has(supportNameKey(statement.name, language))) {
|
|
138
|
+
return { location: statement.location, name: statement.name };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Applies target namespace casing to a protected support name.
|
|
146
|
+
* @param {string} name - Source name.
|
|
147
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
148
|
+
* @returns {string} Comparable name.
|
|
149
|
+
*/
|
|
150
|
+
function supportNameKey(name, language) {
|
|
151
|
+
return language == "php" ? name.toLowerCase() : name;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Emits fixed target-private Task 034 conformance support.
|
|
155
|
+
* @param {import("./writer.js").SourceWriter} writer - Destination writer.
|
|
156
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Authorized module.
|
|
157
|
+
* @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Adopted target.
|
|
158
|
+
* @param {"top" | "members"} [placement] - Java support placement.
|
|
159
|
+
* @returns {void}
|
|
160
|
+
*/
|
|
161
|
+
export function emitEffectSupport(writer, module, language, placement = "top") {
|
|
162
|
+
const linked = writer.stdlibProviderEntries !== undefined;
|
|
163
|
+
if (language == "java" && linked) {
|
|
164
|
+
if (placement != "members" || writer.stdlibProviderShims === undefined)
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
else if (linked || !module.capabilities || !moduleNeedsEffectSupport(module)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const content = language == "php" ? phpSupport : language == "ruby" ? rubySupport : language == "javascript" ? javascriptSupport :
|
|
171
|
+
language == "typescript" ? typescriptSupport :
|
|
172
|
+
writer.stdlibProviderShims !== undefined ? javaProgramNestedSupport + javaMemberSupport :
|
|
173
|
+
placement == "top" ? javaTopSupport : javaMemberSupport;
|
|
174
|
+
writer.synthetic(content, "semantifold-task034-support", [module]);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Emits the public static provider shims for the program-wide used operations on the Java owner module.
|
|
178
|
+
* @param {import("./writer.js").SourceWriter} writer - Destination writer.
|
|
179
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Owner module.
|
|
180
|
+
* @returns {void}
|
|
181
|
+
*/
|
|
182
|
+
export function emitEffectProviderEntries(writer, module) {
|
|
183
|
+
const operations = writer.stdlibProviderShims ?? [];
|
|
184
|
+
if (operations.length == 0)
|
|
185
|
+
return;
|
|
186
|
+
const lines = operations.map((operation) => ` ${javaProviderShims[operation]}`);
|
|
187
|
+
writer.synthetic(`${lines.join("\n")}\n\n`, "semantifold-stdlib-provider-entries", [module]);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Recognizes only the byte-exact protected support emitted by this backend.
|
|
191
|
+
* Frontends use this in addition to parser-shape checks during generated-source reparse.
|
|
192
|
+
* @param {string} source - Complete candidate source.
|
|
193
|
+
* @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Adopted target.
|
|
194
|
+
* @param {"top" | "members"} [placement] - Java support placement.
|
|
195
|
+
* @returns {boolean} Whether the exact protected segment is present.
|
|
196
|
+
*/
|
|
197
|
+
export function hasExactEffectSupport(source, language, placement = "top") {
|
|
198
|
+
const content = language == "php" ? phpSupport : language == "ruby" ? rubySupport : language == "javascript" ? javascriptSupport :
|
|
199
|
+
language == "typescript" ? typescriptSupport : placement == "top" ? javaTopSupport : javaMemberSupport;
|
|
200
|
+
return source.includes(content);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Materializes nested effect sites before their enclosing eager expression.
|
|
204
|
+
* The installed replacements remain active until the next statement begins.
|
|
205
|
+
* @param {import("./writer.js").SourceWriter} writer - Destination writer.
|
|
206
|
+
* @param {import("../semantic/types.js").Statement} statement - Current statement.
|
|
207
|
+
* @param {string} indent - Current target indentation.
|
|
208
|
+
* @param {string} path - Exact statement path.
|
|
209
|
+
* @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Adopted target.
|
|
210
|
+
* @param {(expression: import("../semantic/types.js").Expression, path: string) => void} emit - Target expression emitter.
|
|
211
|
+
* @returns {void}
|
|
212
|
+
*/
|
|
213
|
+
export function emitEffectPrefixes(writer, statement, indent, path, language, emit) {
|
|
214
|
+
/** @type {ExpressionPath[]} */
|
|
215
|
+
const planned = [];
|
|
216
|
+
for (const root of statementExpressionRoots(statement, path))
|
|
217
|
+
collectNestedEffects(root.expression, root.path, root.expression, planned);
|
|
218
|
+
writer.planEffectReplacements(planned.map(({ expression }) => expression));
|
|
219
|
+
for (const { expression, path: expressionPath } of planned) {
|
|
220
|
+
const name = writer.effectTemporaryName(expression);
|
|
221
|
+
const type = effectExpressionType(writer, expression);
|
|
222
|
+
const typeName = emittedTypeName(writer, type, language);
|
|
223
|
+
const declaration = language == "php"
|
|
224
|
+
? `/**\n${indent} * @var ${typeName} $${name}\n${indent} * @semantifold-immutable\n${indent} */\n${indent}$${name} = `
|
|
225
|
+
: language == "ruby"
|
|
226
|
+
? `# @type [${typeName}]\n${indent}# @semantifold-immutable\n${indent}${name} = `
|
|
227
|
+
: language == "javascript" ? `/** @type {${typeName}} */\n${indent}const ${name} = `
|
|
228
|
+
: language == "typescript" ? `const ${name}: ${typeName} = ` : `final ${typeName} ${name} = `;
|
|
229
|
+
writer.synthetic(`${indent}${declaration}`, "exactly-once effect temporary", [expression], [expressionPath]);
|
|
230
|
+
writer.emitEffectDefinition(expression, () => emit(expression, expressionPath));
|
|
231
|
+
writer.synthetic(language == "ruby" ? "\n" : ";\n", "exactly-once effect temporary terminator", [expression], [expressionPath]);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Resolves the result type needed for an effect temporary.
|
|
236
|
+
* @param {import("./writer.js").SourceWriter} writer - Active writer.
|
|
237
|
+
* @param {import("../semantic/types.js").Expression} expression - Effectful expression.
|
|
238
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType | undefined} Result type.
|
|
239
|
+
*/
|
|
240
|
+
function effectExpressionType(writer, expression) {
|
|
241
|
+
if (expression.kind == "EffectCallExpression")
|
|
242
|
+
return writer.effectOperationForId(expression.operation).returnType;
|
|
243
|
+
if (expression.kind == "MethodCallExpression" || expression.kind == "CallExpression") {
|
|
244
|
+
return expression.resolution ? semanticTypeForIdentity(expression.resolution.returnType) : undefined;
|
|
245
|
+
}
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Rehydrates a resolved call result for target-local temporary spelling.
|
|
250
|
+
* @param {import("../semantic/types.js").FunctionReturnTypeIdentity} identity - Exact resolved result identity.
|
|
251
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType} Detached semantic type.
|
|
252
|
+
*/
|
|
253
|
+
function semanticTypeForIdentity(identity) {
|
|
254
|
+
if (typeof identity == "string") {
|
|
255
|
+
return { kind: "TypeReference", name: /** @type {import("../semantic/types.js").FunctionReturnTypeName} */ (identity) };
|
|
256
|
+
}
|
|
257
|
+
if (identity.kind == "ListType")
|
|
258
|
+
return { elementType: semanticTypeForValueIdentity(identity.elementType), kind: "ListType" };
|
|
259
|
+
if (identity.kind == "MapType")
|
|
260
|
+
return { keyType: /** @type {import("../semantic/types.js").TypeReference} */ (semanticTypeForValueIdentity(identity.keyType)), kind: "MapType",
|
|
261
|
+
valueType: semanticTypeForValueIdentity(identity.valueType) };
|
|
262
|
+
if (identity.kind == "OrderedMapType")
|
|
263
|
+
return { keyType: /** @type {import("../semantic/types.js").TypeReference} */ (semanticTypeForValueIdentity(identity.keyType)), kind: "OrderedMapType",
|
|
264
|
+
order: "insertion", valueType: semanticTypeForValueIdentity(identity.valueType) };
|
|
265
|
+
if (identity.kind == "OptionalType")
|
|
266
|
+
return { kind: "OptionalType", valueType: semanticTypeForValueIdentity(identity.valueType) };
|
|
267
|
+
if (identity.kind == "RecordType")
|
|
268
|
+
return { arguments: identity.arguments?.map(semanticTypeForValueIdentity),
|
|
269
|
+
declarationId: identity.declarationId, kind: "RecordType" };
|
|
270
|
+
if (identity.kind == "ReferenceType")
|
|
271
|
+
return { declarationId: identity.declarationId, kind: "ReferenceType" };
|
|
272
|
+
if (identity.kind == "OwnedResourceType")
|
|
273
|
+
return { kind: "OwnedResourceType", resourceId: identity.resourceId };
|
|
274
|
+
if (identity.kind == "OwnedReferenceType")
|
|
275
|
+
return { declarationId: identity.declarationId, kind: "OwnedReferenceType" };
|
|
276
|
+
return { kind: "TypeVariableReference", location: /** @type {never} */ (undefined), parameterId: identity.parameterId };
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Rehydrates one non-void resolved type identity.
|
|
280
|
+
* @param {import("../semantic/types.js").SemanticTypeIdentity} identity - Exact type identity.
|
|
281
|
+
* @returns {import("../semantic/types.js").SemanticValueType} Detached semantic type.
|
|
282
|
+
*/
|
|
283
|
+
function semanticTypeForValueIdentity(identity) {
|
|
284
|
+
return /** @type {import("../semantic/types.js").SemanticValueType} */ (semanticTypeForIdentity(identity));
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Renders the subset of semantic types admitted for synthetic temporaries.
|
|
288
|
+
* @param {import("./writer.js").SourceWriter} writer - Active writer.
|
|
289
|
+
* @param {import("../semantic/types.js").SemanticFunctionReturnType | undefined} type - Semantic type.
|
|
290
|
+
* @param {"php" | "ruby" | "javascript" | "typescript" | "java"} language - Target.
|
|
291
|
+
* @param {boolean} [nested] - Whether Java requires a boxed scalar.
|
|
292
|
+
* @returns {string} Target type spelling.
|
|
293
|
+
*/
|
|
294
|
+
function emittedTypeName(writer, type, language, nested = false) {
|
|
295
|
+
if (!type || type.kind == "TypeReference" && type.name == "void")
|
|
296
|
+
return language == "java" ? "Object" : "unknown";
|
|
297
|
+
if (type.kind == "TypeReference") {
|
|
298
|
+
if (language == "php")
|
|
299
|
+
return type.name == "integer" ? "int" : type.name == "boolean" ? "bool" : "string";
|
|
300
|
+
if (language == "ruby")
|
|
301
|
+
return type.name == "integer" ? "Integer" : type.name == "boolean" ? "Boolean" : "String";
|
|
302
|
+
if (language == "java")
|
|
303
|
+
return type.name == "integer" ? nested ? "Integer" : "int" :
|
|
304
|
+
type.name == "boolean" ? nested ? "Boolean" : "boolean" : "String";
|
|
305
|
+
return type.name == "integer" ? "number" : type.name;
|
|
306
|
+
}
|
|
307
|
+
if (type.kind == "OwnedResourceType")
|
|
308
|
+
return writer.resourceForId(type.resourceId).name;
|
|
309
|
+
if (type.kind == "ReferenceType" || type.kind == "OwnedReferenceType")
|
|
310
|
+
return writer.classNameForId(type.declarationId);
|
|
311
|
+
if (type.kind == "TypeVariableReference")
|
|
312
|
+
return writer.typeParameterForId(type.parameterId).name;
|
|
313
|
+
if (type.kind == "RecordType") {
|
|
314
|
+
const name = writer.recordNameForId(type.declarationId);
|
|
315
|
+
const arguments_ = type.arguments?.map((argument) => emittedTypeName(writer, argument, language, true)) ?? [];
|
|
316
|
+
return arguments_.length == 0 ? name : language == "ruby" ? `${name}[${arguments_.join(",")}]` : `${name}<${arguments_.join(",")}>`;
|
|
317
|
+
}
|
|
318
|
+
if (type.kind == "OptionalType") {
|
|
319
|
+
const value = emittedTypeName(writer, type.valueType, language, true);
|
|
320
|
+
return language == "php" ? `?${value}` : language == "ruby" ? `${value}?` :
|
|
321
|
+
language == "java" ? `java.util.Optional<${value}>` : `${value} | null`;
|
|
322
|
+
}
|
|
323
|
+
if (type.kind == "ListType") {
|
|
324
|
+
const value = emittedTypeName(writer, type.elementType, language, true);
|
|
325
|
+
return language == "php" ? `list<${value}>` : language == "ruby" ? `Array<${value}>` :
|
|
326
|
+
language == "java" ? `java.util.List<${value}>` : `readonly ${value}[]`;
|
|
327
|
+
}
|
|
328
|
+
if (type.kind == "MapType" || type.kind == "OrderedMapType") {
|
|
329
|
+
const key = emittedTypeName(writer, type.keyType, language, true);
|
|
330
|
+
const value = emittedTypeName(writer, type.valueType, language, true);
|
|
331
|
+
if (language == "php")
|
|
332
|
+
return `array<${key},${value}>`;
|
|
333
|
+
if (language == "ruby")
|
|
334
|
+
return `Hash[${key},${value}]`;
|
|
335
|
+
if (language == "java")
|
|
336
|
+
return `${type.kind == "OrderedMapType" ? "java.util.SequencedMap" : "java.util.Map"}<${key},${value}>`;
|
|
337
|
+
return `ReadonlyMap<${key}, ${value}>`;
|
|
338
|
+
}
|
|
339
|
+
return language == "java" ? "Object" : "unknown";
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Returns the expression roots evaluated by one statement.
|
|
343
|
+
* @param {import("../semantic/types.js").Statement} statement - Statement.
|
|
344
|
+
* @param {string} path - Stable statement path.
|
|
345
|
+
* @returns {ExpressionPath[]} Expression roots.
|
|
346
|
+
*/
|
|
347
|
+
function statementExpressionRoots(statement, path) {
|
|
348
|
+
if (statement.kind == "LocalDeclaration")
|
|
349
|
+
return [{ expression: statement.initializer, path: `${path}/initializer` }];
|
|
350
|
+
if (statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
|
|
351
|
+
return [{ expression: statement.expression, path: `${path}/expression` }];
|
|
352
|
+
}
|
|
353
|
+
if (statement.kind == "ReturnStatement")
|
|
354
|
+
return statement.expression ? [{ expression: statement.expression, path: `${path}/expression` }] : [];
|
|
355
|
+
if (statement.kind == "PrivateFieldWriteStatement")
|
|
356
|
+
return [{ expression: statement.expression, path: `${path}/expression` }];
|
|
357
|
+
if (statement.kind == "IfStatement" || statement.kind == "WhileStatement")
|
|
358
|
+
return [{ expression: statement.condition, path: `${path}/condition` }];
|
|
359
|
+
if (statement.kind == "ForEachStatement")
|
|
360
|
+
return [{ expression: statement.list, path: `${path}/list` }];
|
|
361
|
+
if (statement.kind == "ForEachMapStatement")
|
|
362
|
+
return [{ expression: statement.map, path: `${path}/map` }];
|
|
363
|
+
if (statement.kind == "RaiseStatement")
|
|
364
|
+
return [{ expression: statement.error.message, path: `${path}/error/message` }];
|
|
365
|
+
return [];
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Collects nested effect sites in postorder so children are materialized first.
|
|
369
|
+
* @param {import("../semantic/types.js").Expression} expression - Current expression.
|
|
370
|
+
* @param {string} path - Current occurrence path.
|
|
371
|
+
* @param {import("../semantic/types.js").Expression} root - Statement expression root.
|
|
372
|
+
* @param {ExpressionPath[]} output - Ordered plan receiving nested sites.
|
|
373
|
+
* @returns {void}
|
|
374
|
+
*/
|
|
375
|
+
function collectNestedEffects(expression, path, root, output) {
|
|
376
|
+
for (const child of expressionChildren(expression, path))
|
|
377
|
+
collectNestedEffects(child.expression, child.path, root, output);
|
|
378
|
+
if (expression !== root && (expression.kind == "EffectCallExpression" || typeof Reflect.get(expression, "effectSiteId") == "string")) {
|
|
379
|
+
output.push({ expression, path });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Returns path-bearing expression children in evaluation order.
|
|
384
|
+
* @param {import("../semantic/types.js").Expression} expression - Parent expression.
|
|
385
|
+
* @param {string} path - Parent path.
|
|
386
|
+
* @returns {ExpressionPath[]} Children.
|
|
387
|
+
*/
|
|
388
|
+
function expressionChildren(expression, path) {
|
|
389
|
+
if (expression.kind == "CallExpression" || expression.kind == "EffectCallExpression" || expression.kind == "ReferenceConstruction" ||
|
|
390
|
+
expression.kind == "RecordConstruction")
|
|
391
|
+
return expression.arguments.map((child, index) => ({ expression: child, path: `${path}/arguments/${index}` }));
|
|
392
|
+
if (expression.kind == "MethodCallExpression")
|
|
393
|
+
return [
|
|
394
|
+
{ expression: expression.receiver, path: `${path}/receiver` },
|
|
395
|
+
...expression.arguments.map((child, index) => ({ expression: child, path: `${path}/arguments/${index}` }))
|
|
396
|
+
];
|
|
397
|
+
if (expression.kind == "OwnedMoveExpression" || expression.kind == "OwnedBorrowExpression") {
|
|
398
|
+
return [{ expression: expression.expression, path: `${path}/expression` }];
|
|
399
|
+
}
|
|
400
|
+
if (expression.kind == "BinaryExpression")
|
|
401
|
+
return [
|
|
402
|
+
{ expression: expression.left, path: `${path}/left` }, { expression: expression.right, path: `${path}/right` }
|
|
403
|
+
];
|
|
404
|
+
if (expression.kind == "UnaryExpression")
|
|
405
|
+
return [{ expression: expression.operand, path: `${path}/operand` }];
|
|
406
|
+
if (expression.kind == "OptionalSome")
|
|
407
|
+
return [{ expression: expression.value, path: `${path}/value` }];
|
|
408
|
+
if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap") {
|
|
409
|
+
return [{ expression: expression.operand, path: `${path}/operand` }];
|
|
410
|
+
}
|
|
411
|
+
if (expression.kind == "ListLiteral")
|
|
412
|
+
return expression.elements.map((child, index) => ({ expression: child, path: `${path}/elements/${index}` }));
|
|
413
|
+
if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral")
|
|
414
|
+
return expression.entries.flatMap((entry, index) => [
|
|
415
|
+
{ expression: entry.key, path: `${path}/entries/${index}/key` }, { expression: entry.value, path: `${path}/entries/${index}/value` }
|
|
416
|
+
]);
|
|
417
|
+
if (expression.kind == "ListIndexExpression")
|
|
418
|
+
return [
|
|
419
|
+
{ expression: expression.collection, path: `${path}/collection` }, { expression: expression.index, path: `${path}/index` }
|
|
420
|
+
];
|
|
421
|
+
if (expression.kind == "MapLookupExpression")
|
|
422
|
+
return [
|
|
423
|
+
{ expression: expression.collection, path: `${path}/collection` }, { expression: expression.key, path: `${path}/key` }
|
|
424
|
+
];
|
|
425
|
+
if (expression.kind == "CollectionSizeExpression")
|
|
426
|
+
return [{ expression: expression.collection, path: `${path}/collection` }];
|
|
427
|
+
if (expression.kind == "MemberRead")
|
|
428
|
+
return [{ expression: expression.receiver, path: `${path}/receiver` }];
|
|
429
|
+
return [];
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Checks whether generated support is required by a semantic capability node or type.
|
|
433
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
|
|
434
|
+
* @returns {boolean} Whether the protected binding is required.
|
|
435
|
+
*/
|
|
436
|
+
function moduleNeedsEffectSupport(module) {
|
|
437
|
+
/** @type {unknown[]} */
|
|
438
|
+
const pending = [module.entryPoint, ...module.functions, ...module.records ?? [], ...module.errors ?? [], ...module.classes ?? []];
|
|
439
|
+
const seen = new Set();
|
|
440
|
+
while (pending.length > 0) {
|
|
441
|
+
const value = pending.pop();
|
|
442
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
443
|
+
continue;
|
|
444
|
+
seen.add(value);
|
|
445
|
+
const kind = Reflect.get(value, "kind");
|
|
446
|
+
if (kind == "EffectCallExpression" || kind == "OwnedResourceType" || kind == "OwnedReferenceType" ||
|
|
447
|
+
kind == "ErrorType" && /^capability:[0-9]+\/failure:[0-9]+$/u.test(String(Reflect.get(value, "declarationId"))))
|
|
448
|
+
return true;
|
|
449
|
+
for (const [key, child] of Object.entries(value)) {
|
|
450
|
+
if (["location", "sourceProvenance"].includes(key))
|
|
451
|
+
continue;
|
|
452
|
+
if (Array.isArray(child))
|
|
453
|
+
pending.push(...child);
|
|
454
|
+
else if (child && typeof child == "object")
|
|
455
|
+
pending.push(child);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Finds a context excluded from bounded eager lowering.
|
|
462
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
|
|
463
|
+
* @returns {ExcludedEffect | undefined} First deterministic exclusion.
|
|
464
|
+
*/
|
|
465
|
+
function findExcludedEffectContext(module) {
|
|
466
|
+
/** @type {object[]} */
|
|
467
|
+
const owners = [...module.functions.filter((owner) => owner && typeof owner == "object"), module.entryPoint];
|
|
468
|
+
for (const declaration of module.classes ?? []) {
|
|
469
|
+
if (!declaration || typeof declaration != "object")
|
|
470
|
+
continue;
|
|
471
|
+
if (declaration.constructor && typeof declaration.constructor == "object")
|
|
472
|
+
owners.push(declaration.constructor);
|
|
473
|
+
if (Array.isArray(declaration.methods))
|
|
474
|
+
owners.push(...declaration.methods.filter((owner) => owner && typeof owner == "object"));
|
|
475
|
+
}
|
|
476
|
+
for (const owner of owners) {
|
|
477
|
+
const body = Reflect.get(owner, "body");
|
|
478
|
+
if (!body || typeof body != "object")
|
|
479
|
+
continue;
|
|
480
|
+
const found = blockExcluded(/** @type {import("../semantic/types.js").Block} */ (body));
|
|
481
|
+
if (found)
|
|
482
|
+
return found;
|
|
483
|
+
}
|
|
484
|
+
return undefined;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Finds an excluded context in one structured block.
|
|
488
|
+
* @param {import("../semantic/types.js").Block} block - Semantic block.
|
|
489
|
+
* @returns {ExcludedEffect | undefined} First deterministic exclusion.
|
|
490
|
+
*/
|
|
491
|
+
function blockExcluded(block) {
|
|
492
|
+
if (!block || typeof block != "object" || !Array.isArray(block.statements))
|
|
493
|
+
return undefined;
|
|
494
|
+
for (const statement of block.statements) {
|
|
495
|
+
if (!statement || typeof statement != "object")
|
|
496
|
+
continue;
|
|
497
|
+
if (statement.kind == "WhileStatement" && containsEffect(statement.condition)) {
|
|
498
|
+
return { detail: "effectful condition-controlled loop condition", location: statement.condition.location };
|
|
499
|
+
}
|
|
500
|
+
const expressions = statement.kind == "LocalDeclaration" ? [statement.initializer] :
|
|
501
|
+
statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? [statement.expression] :
|
|
502
|
+
statement.kind == "ReturnStatement" ? statement.expression ? [statement.expression] : [] :
|
|
503
|
+
statement.kind == "IfStatement" ? [statement.condition] : statement.kind == "ForEachStatement" ? [statement.list] :
|
|
504
|
+
statement.kind == "ForEachMapStatement" ? [statement.map] : statement.kind == "PrivateFieldWriteStatement" ? [statement.expression] :
|
|
505
|
+
statement.kind == "RaiseStatement" ? [statement.error.message] : [];
|
|
506
|
+
for (const expression of expressions) {
|
|
507
|
+
const conditional = findConditionalEffect(expression);
|
|
508
|
+
if (conditional)
|
|
509
|
+
return { detail: "effectful short-circuit BooleanAnd/BooleanOr expression", location: conditional.location };
|
|
510
|
+
}
|
|
511
|
+
const nested = statement.kind == "IfStatement" ? [statement.consequent, ...(statement.alternate ? [statement.alternate] : [])] :
|
|
512
|
+
statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement" || statement.kind == "WhileStatement" ? [statement.body] :
|
|
513
|
+
statement.kind == "TryStatement" ? [statement.body, statement.catchBody] : [];
|
|
514
|
+
for (const child of nested) {
|
|
515
|
+
const found = blockExcluded(child);
|
|
516
|
+
if (found)
|
|
517
|
+
return found;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return undefined;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Finds an effect below a short-circuit operator.
|
|
524
|
+
* @param {import("../semantic/types.js").Expression} expression - Expression root.
|
|
525
|
+
* @returns {import("../semantic/types.js").Expression | undefined} Invalid conditional effect.
|
|
526
|
+
*/
|
|
527
|
+
function findConditionalEffect(expression) {
|
|
528
|
+
if (!expression || typeof expression != "object")
|
|
529
|
+
return undefined;
|
|
530
|
+
if (expression.kind == "BinaryExpression" && ["BooleanAnd", "BooleanOr"].includes(expression.operation) &&
|
|
531
|
+
(containsEffect(expression.left) || containsEffect(expression.right)))
|
|
532
|
+
return expression;
|
|
533
|
+
for (const child of children(expression)) {
|
|
534
|
+
const found = findConditionalEffect(child);
|
|
535
|
+
if (found)
|
|
536
|
+
return found;
|
|
537
|
+
}
|
|
538
|
+
return undefined;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Checks whether an expression evaluates an effect.
|
|
542
|
+
* @param {import("../semantic/types.js").Expression} expression - Expression root.
|
|
543
|
+
* @returns {boolean} Whether an effect is reachable.
|
|
544
|
+
*/
|
|
545
|
+
function containsEffect(expression) {
|
|
546
|
+
if (!expression || typeof expression != "object")
|
|
547
|
+
return false;
|
|
548
|
+
return expression.kind == "EffectCallExpression" || Boolean(Reflect.get(expression, "effectSiteId")) || children(expression).some(containsEffect);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Returns child expressions in evaluation order.
|
|
552
|
+
* @param {import("../semantic/types.js").Expression} expression - Parent expression.
|
|
553
|
+
* @returns {import("../semantic/types.js").Expression[]} Children.
|
|
554
|
+
*/
|
|
555
|
+
function children(expression) {
|
|
556
|
+
if (!expression || typeof expression != "object")
|
|
557
|
+
return [];
|
|
558
|
+
if (expression.kind == "CallExpression" || expression.kind == "EffectCallExpression" || expression.kind == "ReferenceConstruction" ||
|
|
559
|
+
expression.kind == "RecordConstruction")
|
|
560
|
+
return expression.arguments;
|
|
561
|
+
if (expression.kind == "MethodCallExpression")
|
|
562
|
+
return [expression.receiver, ...expression.arguments];
|
|
563
|
+
if (expression.kind == "OwnedMoveExpression" || expression.kind == "OwnedBorrowExpression")
|
|
564
|
+
return [expression.expression];
|
|
565
|
+
if (expression.kind == "BinaryExpression")
|
|
566
|
+
return [expression.left, expression.right];
|
|
567
|
+
if (expression.kind == "UnaryExpression")
|
|
568
|
+
return [expression.operand];
|
|
569
|
+
if (expression.kind == "OptionalSome")
|
|
570
|
+
return [expression.value];
|
|
571
|
+
if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap")
|
|
572
|
+
return [expression.operand];
|
|
573
|
+
if (expression.kind == "ListLiteral")
|
|
574
|
+
return expression.elements;
|
|
575
|
+
if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral")
|
|
576
|
+
return expression.entries.flatMap(({ key, value }) => [key, value]);
|
|
577
|
+
if (expression.kind == "ListIndexExpression")
|
|
578
|
+
return [expression.collection, expression.index];
|
|
579
|
+
if (expression.kind == "MapLookupExpression")
|
|
580
|
+
return [expression.collection, expression.key];
|
|
581
|
+
if (expression.kind == "CollectionSizeExpression")
|
|
582
|
+
return [expression.collection];
|
|
583
|
+
if (expression.kind == "MemberRead")
|
|
584
|
+
return [expression.receiver];
|
|
585
|
+
return [];
|
|
586
|
+
}
|
|
587
|
+
const phpSupport = `/* semantifold-task034-support */
|
|
588
|
+
final class ProbeOperationFailure extends RuntimeException {}
|
|
589
|
+
final class ProbeAcquireFailure extends RuntimeException {}
|
|
590
|
+
final class ProbeReadFailure extends RuntimeException {}
|
|
591
|
+
final class ProbeCloseFailure extends RuntimeException {}
|
|
592
|
+
final class ProbeResourceClosed extends RuntimeException {}
|
|
593
|
+
final class ProbeResource {
|
|
594
|
+
public bool $closed = false;
|
|
595
|
+
public function __construct(public mixed $handle) {}
|
|
596
|
+
}
|
|
597
|
+
$GLOBALS['__semantifold_task034_trace'] = [];
|
|
598
|
+
function probeEffect(string $label, int $value, bool $fail): int {
|
|
599
|
+
$GLOBALS['__semantifold_task034_trace'][] = 'effect:' . $label;
|
|
600
|
+
if ($fail) throw new ProbeOperationFailure('ProbeOperationFailure');
|
|
601
|
+
return $value;
|
|
602
|
+
}
|
|
603
|
+
function probeAcquire(bool $fail): ProbeResource {
|
|
604
|
+
$GLOBALS['__semantifold_task034_trace'][] = 'acquire';
|
|
605
|
+
if ($fail) throw new ProbeAcquireFailure('ProbeAcquireFailure');
|
|
606
|
+
try { $handle = @fopen((string) getenv('SEMANTIFOLD_TASK034_PROBE_PATH'), 'rb'); }
|
|
607
|
+
catch (Throwable) { throw new ProbeAcquireFailure('ProbeAcquireFailure'); }
|
|
608
|
+
if ($handle === false) throw new ProbeAcquireFailure('ProbeAcquireFailure');
|
|
609
|
+
return new ProbeResource($handle);
|
|
610
|
+
}
|
|
611
|
+
function probeRead(ProbeResource $resource, bool $fail): ?string {
|
|
612
|
+
if ($resource->closed) throw new ProbeResourceClosed('ProbeResourceClosed');
|
|
613
|
+
$GLOBALS['__semantifold_task034_trace'][] = 'read';
|
|
614
|
+
if ($fail) throw new ProbeReadFailure('ProbeReadFailure');
|
|
615
|
+
try { $line = @fgets($resource->handle); }
|
|
616
|
+
catch (Throwable) { throw new ProbeReadFailure('ProbeReadFailure'); }
|
|
617
|
+
if ($line === false) {
|
|
618
|
+
if (feof($resource->handle)) return null;
|
|
619
|
+
throw new ProbeReadFailure('ProbeReadFailure');
|
|
620
|
+
}
|
|
621
|
+
return rtrim($line, "\\r\\n");
|
|
622
|
+
}
|
|
623
|
+
function probeClose(ProbeResource $resource, bool $fail): void {
|
|
624
|
+
if ($resource->closed) throw new ProbeResourceClosed('ProbeResourceClosed');
|
|
625
|
+
$GLOBALS['__semantifold_task034_trace'][] = 'close';
|
|
626
|
+
try { $closed = @fclose($resource->handle); }
|
|
627
|
+
catch (Throwable) { $resource->closed = true; throw new ProbeCloseFailure('ProbeCloseFailure'); }
|
|
628
|
+
$resource->closed = true;
|
|
629
|
+
if ($fail || !$closed) throw new ProbeCloseFailure('ProbeCloseFailure');
|
|
630
|
+
}
|
|
631
|
+
function probeTrace(): string { return implode(',', $GLOBALS['__semantifold_task034_trace']); }
|
|
632
|
+
/* semantifold-task034-support-end */
|
|
633
|
+
|
|
634
|
+
`;
|
|
635
|
+
const rubySupport = `# semantifold-task034-support
|
|
636
|
+
class ProbeOperationFailure < StandardError; end
|
|
637
|
+
class ProbeAcquireFailure < StandardError; end
|
|
638
|
+
class ProbeReadFailure < StandardError; end
|
|
639
|
+
class ProbeCloseFailure < StandardError; end
|
|
640
|
+
class ProbeResourceClosed < StandardError; end
|
|
641
|
+
class ProbeResource
|
|
642
|
+
attr_accessor :handle, :closed
|
|
643
|
+
def initialize(handle); @handle = handle; @closed = false; end
|
|
644
|
+
end
|
|
645
|
+
$__semantifold_task034_trace = []
|
|
646
|
+
def probeEffect(label, value, fail_value)
|
|
647
|
+
$__semantifold_task034_trace << "effect:#{label}"
|
|
648
|
+
raise ProbeOperationFailure, "ProbeOperationFailure" if fail_value
|
|
649
|
+
value
|
|
650
|
+
end
|
|
651
|
+
def probeAcquire(fail_value)
|
|
652
|
+
$__semantifold_task034_trace << "acquire"
|
|
653
|
+
raise ProbeAcquireFailure, "ProbeAcquireFailure" if fail_value
|
|
654
|
+
begin; ProbeResource.new(File.open(ENV.fetch("SEMANTIFOLD_TASK034_PROBE_PATH"), "r")); rescue ProbeAcquireFailure; raise; rescue StandardError; raise ProbeAcquireFailure, "ProbeAcquireFailure"; end
|
|
655
|
+
end
|
|
656
|
+
def probeRead(resource, fail_value)
|
|
657
|
+
raise ProbeResourceClosed, "ProbeResourceClosed" if resource.closed
|
|
658
|
+
$__semantifold_task034_trace << "read"
|
|
659
|
+
raise ProbeReadFailure, "ProbeReadFailure" if fail_value
|
|
660
|
+
begin; value = resource.handle.gets; value.nil? ? nil : value.chomp; rescue ProbeReadFailure; raise; rescue StandardError; raise ProbeReadFailure, "ProbeReadFailure"; end
|
|
661
|
+
end
|
|
662
|
+
def probeClose(resource, fail_value)
|
|
663
|
+
raise ProbeResourceClosed, "ProbeResourceClosed" if resource.closed
|
|
664
|
+
$__semantifold_task034_trace << "close"
|
|
665
|
+
begin; resource.handle.close; rescue StandardError; resource.closed = true; raise ProbeCloseFailure, "ProbeCloseFailure"; end
|
|
666
|
+
resource.closed = true
|
|
667
|
+
raise ProbeCloseFailure, "ProbeCloseFailure" if fail_value
|
|
668
|
+
nil
|
|
669
|
+
end
|
|
670
|
+
def probeTrace; $__semantifold_task034_trace.join(","); end
|
|
671
|
+
# semantifold-task034-support-end
|
|
672
|
+
|
|
673
|
+
`;
|
|
674
|
+
const javascriptSupport = `/* semantifold-task034-support */
|
|
675
|
+
const __semantifoldTask034Fs = process.getBuiltinModule("node:fs")
|
|
676
|
+
class ProbeOperationFailure extends Error {}
|
|
677
|
+
class ProbeAcquireFailure extends Error {}
|
|
678
|
+
class ProbeReadFailure extends Error {}
|
|
679
|
+
class ProbeCloseFailure extends Error {}
|
|
680
|
+
class ProbeResourceClosed extends Error {}
|
|
681
|
+
class ProbeResource { constructor(handle) { this.handle = handle; this.closed = false; this.position = 0 } }
|
|
682
|
+
const __semantifoldTask034Trace = []
|
|
683
|
+
function probeEffect(label, value, fail) { __semantifoldTask034Trace.push(\`effect:\${label}\`); if (fail) throw new ProbeOperationFailure("ProbeOperationFailure"); return value }
|
|
684
|
+
function probeAcquire(fail) { __semantifoldTask034Trace.push("acquire"); if (fail) throw new ProbeAcquireFailure("ProbeAcquireFailure"); try { return new ProbeResource(__semantifoldTask034Fs.openSync(process.env.SEMANTIFOLD_TASK034_PROBE_PATH, "r")) } catch { throw new ProbeAcquireFailure("ProbeAcquireFailure") } }
|
|
685
|
+
function probeRead(resource, fail) { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("read"); if (fail) throw new ProbeReadFailure("ProbeReadFailure"); try { const bytes = []; const buffer = Buffer.alloc(1); while (true) { const count = __semantifoldTask034Fs.readSync(resource.handle, buffer, 0, 1, resource.position++); if (count === 0) return bytes.length === 0 ? null : Buffer.from(bytes).toString("utf8"); if (buffer[0] === 10) return Buffer.from(bytes).toString("utf8").replace(/\\r$/u, ""); bytes.push(buffer[0]) } } catch { throw new ProbeReadFailure("ProbeReadFailure") } }
|
|
686
|
+
function probeClose(resource, fail) { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("close"); try { __semantifoldTask034Fs.closeSync(resource.handle) } catch { resource.closed = true; throw new ProbeCloseFailure("ProbeCloseFailure") } resource.closed = true; if (fail) throw new ProbeCloseFailure("ProbeCloseFailure") }
|
|
687
|
+
function probeTrace() { return __semantifoldTask034Trace.join(",") }
|
|
688
|
+
/* semantifold-task034-support-end */
|
|
689
|
+
|
|
690
|
+
`;
|
|
691
|
+
const typescriptSupport = `/* semantifold-task034-support */
|
|
692
|
+
const __semantifoldTask034Fs = process.getBuiltinModule("node:fs")
|
|
693
|
+
class ProbeOperationFailure extends Error {}
|
|
694
|
+
class ProbeAcquireFailure extends Error {}
|
|
695
|
+
class ProbeReadFailure extends Error {}
|
|
696
|
+
class ProbeCloseFailure extends Error {}
|
|
697
|
+
class ProbeResourceClosed extends Error {}
|
|
698
|
+
class ProbeResource { closed = false; position = 0; constructor(readonly handle: number) {} }
|
|
699
|
+
const __semantifoldTask034Trace: string[] = []
|
|
700
|
+
function probeEffect(label: string, value: number, fail: boolean): number { __semantifoldTask034Trace.push(\`effect:\${label}\`); if (fail) throw new ProbeOperationFailure("ProbeOperationFailure"); return value }
|
|
701
|
+
function probeAcquire(fail: boolean): ProbeResource { __semantifoldTask034Trace.push("acquire"); if (fail) throw new ProbeAcquireFailure("ProbeAcquireFailure"); try { return new ProbeResource(__semantifoldTask034Fs.openSync(process.env.SEMANTIFOLD_TASK034_PROBE_PATH as string, "r")) } catch { throw new ProbeAcquireFailure("ProbeAcquireFailure") } }
|
|
702
|
+
function probeRead(resource: ProbeResource, fail: boolean): string | null { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("read"); if (fail) throw new ProbeReadFailure("ProbeReadFailure"); try { const bytes: number[] = []; const buffer = Buffer.alloc(1); while (true) { const count = __semantifoldTask034Fs.readSync(resource.handle, buffer, 0, 1, resource.position++); if (count === 0) return bytes.length === 0 ? null : Buffer.from(bytes).toString("utf8"); if (buffer[0] === 10) return Buffer.from(bytes).toString("utf8").replace(/\\r$/u, ""); bytes.push(buffer[0]) } } catch { throw new ProbeReadFailure("ProbeReadFailure") } }
|
|
703
|
+
function probeClose(resource: ProbeResource, fail: boolean): void { if (resource.closed) throw new ProbeResourceClosed("ProbeResourceClosed"); __semantifoldTask034Trace.push("close"); try { __semantifoldTask034Fs.closeSync(resource.handle) } catch { resource.closed = true; throw new ProbeCloseFailure("ProbeCloseFailure") } resource.closed = true; if (fail) throw new ProbeCloseFailure("ProbeCloseFailure") }
|
|
704
|
+
function probeTrace(): string { return __semantifoldTask034Trace.join(",") }
|
|
705
|
+
/* semantifold-task034-support-end */
|
|
706
|
+
|
|
707
|
+
`;
|
|
708
|
+
const javaTopSupport = `// semantifold-task034-support
|
|
709
|
+
final class ProbeOperationFailure extends RuntimeException { ProbeOperationFailure() { super("ProbeOperationFailure"); } }
|
|
710
|
+
final class ProbeAcquireFailure extends RuntimeException { ProbeAcquireFailure() { super("ProbeAcquireFailure"); } }
|
|
711
|
+
final class ProbeReadFailure extends RuntimeException { ProbeReadFailure() { super("ProbeReadFailure"); } }
|
|
712
|
+
final class ProbeCloseFailure extends RuntimeException { ProbeCloseFailure() { super("ProbeCloseFailure"); } }
|
|
713
|
+
final class ProbeResourceClosed extends RuntimeException { ProbeResourceClosed() { super("ProbeResourceClosed"); } }
|
|
714
|
+
final class ProbeResource { final java.nio.channels.FileChannel handle; boolean closed = false; ProbeResource(java.nio.channels.FileChannel handle) { this.handle = handle; } }
|
|
715
|
+
// semantifold-task034-support-top-end
|
|
716
|
+
|
|
717
|
+
`;
|
|
718
|
+
const javaMemberSupport = ` // semantifold-task034-support-members
|
|
719
|
+
private static final java.util.ArrayList<String> __semantifoldTask034Trace = new java.util.ArrayList<>();
|
|
720
|
+
static int probeEffect(String label, int value, boolean fail) { __semantifoldTask034Trace.add("effect:" + label); if (fail) throw new ProbeOperationFailure(); return value; }
|
|
721
|
+
static ProbeResource probeAcquire(boolean fail) { __semantifoldTask034Trace.add("acquire"); if (fail) throw new ProbeAcquireFailure(); try { return new ProbeResource(java.nio.channels.FileChannel.open(java.nio.file.Path.of(System.getenv("SEMANTIFOLD_TASK034_PROBE_PATH")))); } catch (RuntimeException | java.io.IOException exception) { throw new ProbeAcquireFailure(); } }
|
|
722
|
+
static java.util.Optional<String> probeRead(ProbeResource resource, boolean fail) { if (resource.closed) throw new ProbeResourceClosed(); __semantifoldTask034Trace.add("read"); if (fail) throw new ProbeReadFailure(); try { java.io.ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream(); java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(1); while (true) { buffer.clear(); int count = resource.handle.read(buffer); if (count < 0) return bytes.size() == 0 ? java.util.Optional.empty() : java.util.Optional.of(bytes.toString(java.nio.charset.StandardCharsets.UTF_8)); buffer.flip(); byte value = buffer.get(); if (value == 10) return java.util.Optional.of(bytes.toString(java.nio.charset.StandardCharsets.UTF_8).replaceFirst("\\r$", "")); bytes.write(value); } } catch (java.io.IOException exception) { throw new ProbeReadFailure(); } }
|
|
723
|
+
static void probeClose(ProbeResource resource, boolean fail) { if (resource.closed) throw new ProbeResourceClosed(); __semantifoldTask034Trace.add("close"); try { resource.handle.close(); } catch (java.io.IOException exception) { resource.closed = true; throw new ProbeCloseFailure(); } resource.closed = true; if (fail) throw new ProbeCloseFailure(); }
|
|
724
|
+
static String probeTrace() { return String.join(",", __semantifoldTask034Trace); }
|
|
725
|
+
// semantifold-task034-support-members-end
|
|
726
|
+
|
|
727
|
+
`;
|
|
728
|
+
const javaProgramNestedSupport = ` // semantifold-task034-support-program
|
|
729
|
+
public static final class ProbeOperationFailure extends RuntimeException { ProbeOperationFailure() { super("ProbeOperationFailure"); } }
|
|
730
|
+
public static final class ProbeAcquireFailure extends RuntimeException { ProbeAcquireFailure() { super("ProbeAcquireFailure"); } }
|
|
731
|
+
public static final class ProbeReadFailure extends RuntimeException { ProbeReadFailure() { super("ProbeReadFailure"); } }
|
|
732
|
+
public static final class ProbeCloseFailure extends RuntimeException { ProbeCloseFailure() { super("ProbeCloseFailure"); } }
|
|
733
|
+
public static final class ProbeResourceClosed extends RuntimeException { ProbeResourceClosed() { super("ProbeResourceClosed"); } }
|
|
734
|
+
public static final class ProbeResource { final java.nio.channels.FileChannel handle; boolean closed = false; ProbeResource(java.nio.channels.FileChannel handle) { this.handle = handle; } }
|
|
735
|
+
// semantifold-task034-support-program-end
|
|
736
|
+
|
|
737
|
+
`;
|
|
738
|
+
/** @type {Record<string, string>} */
|
|
739
|
+
const javaProviderShims = {
|
|
740
|
+
probeAcquire: "public static ProbeResource __semantifold_provider_java_probeAcquire(boolean fail) { return probeAcquire(fail); }",
|
|
741
|
+
probeClose: "public static void __semantifold_provider_java_probeClose(ProbeResource resource, boolean fail) { probeClose(resource, fail); }",
|
|
742
|
+
probeEffect: "public static int __semantifold_provider_java_probeEffect(String label, int value, boolean fail) { return probeEffect(label, value, fail); }",
|
|
743
|
+
probeRead: "public static java.util.Optional<String> __semantifold_provider_java_probeRead(ProbeResource resource, boolean fail) { return probeRead(resource, fail); }",
|
|
744
|
+
probeTrace: "public static String __semantifold_provider_java_probeTrace() { return probeTrace(); }"
|
|
745
|
+
};
|
|
746
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kcy9lZmZlY3RzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0RCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQTtBQUVsRSxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBQ25GLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDakMsb0JBQW9CLEVBQUUsc0JBQXNCLEVBQUUsMkJBQTJCLEVBQUUseUJBQXlCO0NBQ3JHLENBQUMsQ0FBQTtBQUNGLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDcEMsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUsa0JBQWtCLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsZUFBZTtJQUMvSCxhQUFhLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsWUFBWTtDQUN2RSxDQUFDLENBQUE7QUFFRixzR0FBc0c7QUFDdEcsMEdBQTBHO0FBRTFHOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLDJCQUEyQixDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxHQUFHLEVBQUU7SUFDeEUsTUFBTSxZQUFZLEdBQUcsTUFBTSxFQUFFLFlBQVksQ0FBQTtJQUV6QyxJQUFJLFlBQVksS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUMvQixNQUFNLFlBQVksR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUE7UUFFNUMsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsaUZBQWlGO1lBQy9HLHdFQUF3RSxD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QkFBaUIsR0FBRzs7Ozs7Ozs7Ozs7Ozs7OztDQWdCekIsQ0FBQTtBQUVELE1BQU0sY0FBYyxHQUFHOzs7Ozs7Ozs7Q0FTdEIsQ0FBQTtBQUVELE1BQU0saUJBQWlCLEdBQUc7Ozs7Ozs7OztDQVN6QixDQUFBO0FBRUQsTUFBTSx3QkFBd0IsR0FBRzs7Ozs7Ozs7O0NBU2hDLENBQUE7QUFFRCxxQ0FBcUM7QUFDckMsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixZQUFZLEVBQUUsbUhBQW1IO0lBQ2pJLFVBQVUsRUFBRSxpSUFBaUk7SUFDN0ksV0FBVyxFQUFFLDhJQUE4STtJQUMzSixTQUFTLEVBQUUsNEpBQTRKO0lBQ3ZLLFVBQVUsRUFBRSx3RkFBd0Y7Q0FDckcsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge3Vuc3VwcG9ydGVkQ2FwYWJpbGl0eX0gZnJvbSBcIi4uL2RpYWdub3N0aWMuanNcIlxuaW1wb3J0IHtpc1Rhc2swMzRSZXNvdXJjZVByb2JlfSBmcm9tIFwiLi4vc2VtYW50aWMvY2FwYWJpbGl0aWVzLmpzXCJcblxuY29uc3QgYWRvcHRlZFRhcmdldHMgPSBuZXcgU2V0KFtcInBocFwiLCBcInJ1YnlcIiwgXCJqYXZhc2NyaXB0XCIsIFwidHlwZXNjcmlwdFwiLCBcImphdmFcIl0pXG5jb25zdCB0YXNrMDM3QXV0aG9yaXRpZXMgPSBuZXcgU2V0KFtcbiAgXCJzZW1hbnRpZm9sZC5vdXRwdXRcIiwgXCJzZW1hbnRpZm9sZC5yZXNvdXJjZVwiLCBcInNlbWFudGlmb2xkLnNvY2tldC1jbGllbnRcIiwgXCJzZW1hbnRpZm9sZC50ZXh0LXN0cmVhbVwiXG5dKVxuY29uc3QgcHJvdGVjdGVkU3VwcG9ydE5hbWVzID0gbmV3IFNldChbXG4gIFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIsIFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiLCBcIlByb2JlUmVhZEZhaWx1cmVcIiwgXCJQcm9iZUNsb3NlRmFpbHVyZVwiLCBcIlByb2JlUmVzb3VyY2VDbG9zZWRcIiwgXCJQcm9iZVJlc291cmNlXCIsXG4gIFwicHJvYmVFZmZlY3RcIiwgXCJwcm9iZUFjcXVpcmVcIiwgXCJwcm9iZVJlYWRcIiwgXCJwcm9iZUNsb3NlXCIsIFwicHJvYmVUcmFjZVwiXG5dKVxuXG4vKiogQHR5cGVkZWYge3tleHByZXNzaW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9uLCBwYXRoOiBzdHJpbmd9fSBFeHByZXNzaW9uUGF0aCAqL1xuLyoqIEB0eXBlZGVmIHt7ZGV0YWlsOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn19IEV4Y2x1ZGVkRWZmZWN0ICovXG5cbi8qKlxuICogVmFsaWRhdGVzIFRhc2sgMDM0IHRhcmdldCBzdXBwb3J0IGJlZm9yZSBhIFNvdXJjZVdyaXRlciBpcyBhbGxvY2F0ZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBDYW5kaWRhdGUgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gUmVxdWVzdGVkIHRhcmdldC5cbiAqIEBwYXJhbSB7e3VzZWRPcGVyYXRpb25zPzogcmVhZG9ubHkgc3RyaW5nW119fSBbb3B0aW9uc10gLSBQcm9ncmFtLXdpZGUgdXNlZCBjYW5vbmljYWxcbiAqICAgb3BlcmF0aW9ucyBmb3IgYSBsaW5rZWQgc3RkbGliIHByb3ZpZGVyOyByZXN0cmljdHMgdGhlIHJlc2VydmVkIHN1cHBvcnQgc3VyZmFjZSB0byB0aGVcbiAqICAgb3BlcmF0aW9ucyBhY3R1YWxseSBtYXRlcmlhbGl6ZWQgaW4gdGhlIHByb3ZpZGVyIGFydGlmYWN0LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVmbGlnaHRFZmZlY3RDYXBhYmlsaXRpZXMobW9kdWxlLCBsYW5ndWFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IGNhcGFiaWxpdGllcyA9IG1vZHVsZT8uY2FwYWJpbGl0aWVzXG5cbiAgaWYgKGNhcGFiaWxpdGllcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgdW5hdXRob3JpemVkID0gZmluZFRhc2swMzROb2RlKG1vZHVsZSlcblxuICAgIGlmICh1bmF1dGhvcml6ZWQpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJNSVNTSU5HX0NBUEFCSUxJVFlfQVVUSE9SSVRZOiBUYXNrIDAzNCBJUiByZXF1aXJlcyBpdHMgY29tcGlsZXIgYXV0aG9yaXR5IGdyYXBoXCIsXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWR9ICovIChSZWZsZWN0LmdldCh1bmF1dGhvcml6ZWQsIFwibG9jYXRpb25cIikgPz8gbW9kdWxlPy5sb2NhdGlvbikpXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmICghQXJyYXkuaXNBcnJheShjYXBhYmlsaXRpZXMpIHx8IGNhcGFiaWxpdGllcy5sZW5ndGggPT0gMCkge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgb3IgZW1wdHkgVGFzayAwMzQgY2FwYWJpbGl0eSBncmFwaFwiLCBtb2R1bGU/LmxvY2F0aW9uKVxuICB9XG4gIGlmICghYWRvcHRlZFRhcmdldHMuaGFzKGxhbmd1YWdlKSkge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAzNCBlZmZlY3RmdWwgY2FwYWJpbGl0aWVzIGFuZCBvd25lZCByZXNvdXJjZXNcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IHRhc2swMzcgPSBsYW5ndWFnZSA9PSBcInBocFwiICYmIGNhcGFiaWxpdGllcy5ldmVyeSgoY2FwYWJpbGl0eSkgPT4gdGFzazAzN0F1dGhvcml0aWVzLmhhcyhjYXBhYmlsaXR5LmF1dGhvcml0eUlkKSlcblxuICBpZiAoIWlzVGFzazAzNFJlc291cmNlUHJvYmUoY2FwYWJpbGl0aWVzKSAmJiAhdGFzazAzNykge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJ1bmJvdW5kIFRhc2sgMDM0IGNhcGFiaWxpdHkgYXV0aG9yaXR5XCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgfVxuICBpZiAoIUFycmF5LmlzQXJyYXkobW9kdWxlLmZ1bmN0aW9ucykgfHwgIW1vZHVsZS5lbnRyeVBvaW50IHx8IHR5cGVvZiBtb2R1bGUuZW50cnlQb2ludCAhPSBcIm9iamVjdFwiIHx8XG4gICAgIW1vZHVsZS5lbnRyeVBvaW50LmJvZHkgfHwgIUFycmF5LmlzQXJyYXkobW9kdWxlLmVudHJ5UG9pbnQuYm9keS5zdGF0ZW1lbnRzKSB8fFxuICAgIFttb2R1bGUucmVjb3JkcywgbW9kdWxlLmNsYXNzZXMsIG1vZHVsZS5lcnJvcnNdLnNvbWUoKGRlY2xhcmF0aW9ucykgPT4gZGVjbGFyYXRpb25zICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb25zKSkpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIFRhc2sgMDM0IHNlbWFudGljIG1vZHVsZVwiLCBtb2R1bGUubG9jYXRpb24pXG4gIH1cbiAgY29uc3QgY29sbGlzaW9uID0gbW9kdWxlTmVlZHNFZmZlY3RTdXBwb3J0KG1vZHVsZSkgPyBmaW5kU3VwcG9ydENvbGxpc2lvbihtb2R1bGUsIGxhbmd1YWdlLCBvcHRpb25zLnVzZWRPcGVyYXRpb25zKSA6IHVuZGVmaW5lZFxuXG4gIGlmIChjb2xsaXNpb24pIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYHByb3RlY3RlZCBUYXNrIDAzNCBzdXBwb3J0IG5hbWUgJyR7Y29sbGlzaW9uLm5hbWV9J2AsIGNvbGxpc2lvbi5sb2NhdGlvbilcbiAgY29uc3QgZXhjbHVkZWQgPSBmaW5kRXhjbHVkZWRFZmZlY3RDb250ZXh0KG1vZHVsZSlcbiAgaWYgKGV4Y2x1ZGVkKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGV4Y2x1ZGVkLmRldGFpbCwgZXhjbHVkZWQubG9jYXRpb24pXG59XG5cbi8qKlxuICogRmluZHMgY29tcGlsZXItYXV0aG9yaXplZCBUYXNrIDAzNCBJUiB0aGF0IGhhcyBiZWVuIGRldGFjaGVkIGZyb20gaXRzIGF1dGhvcml0eSBncmFwaC5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgc2VtYW50aWMgZ3JhcGguXG4gKiBAcGFyYW0ge1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBDeWNsZSBwcm90ZWN0aW9uLlxuICogQHJldHVybnMge29iamVjdCB8IHVuZGVmaW5lZH0gRmlyc3QgdW5hdXRob3JpemVkIFRhc2sgMDM0IG5vZGUuXG4gKi9cbmZ1bmN0aW9uIGZpbmRUYXNrMDM0Tm9kZSh2YWx1ZSwgc2VlbiA9IG5ldyBTZXQoKSkge1xuICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuIHVuZGVmaW5lZFxuICBzZWVuLmFkZCh2YWx1ZSlcbiAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGNvbnN0IGtpbmQgPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJraW5kXCIpXG5cbiAgICBpZiAoW1wiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIiwgXCJPd25lZEJvcnJvd0V4cHJlc3Npb25cIiwgXCJPd25lZE1vdmVFeHByZXNzaW9uXCIsIFwiT3duZWRSZWZlcmVuY2VUeXBlXCIsIFwiT3duZWRSZXNvdXJjZVR5cGVcIl0uaW5jbHVkZXMoU3RyaW5nKGtpbmQpKSB8fFxuICAgICAga2luZCA9PSBcIkVycm9yVHlwZVwiICYmIC9eY2FwYWJpbGl0eTpbMC05XStcXC9mYWlsdXJlOlswLTldKyQvdS50ZXN0KFN0cmluZyhSZWZsZWN0LmdldCh2YWx1ZSwgXCJkZWNsYXJhdGlvbklkXCIpKSkpIHJldHVybiB2YWx1ZVxuICB9XG4gIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgIGlmIChbXCJsb2NhdGlvblwiLCBcInNvdXJjZVByb3ZlbmFuY2VcIl0uaW5jbHVkZXMoa2V5KSkgY29udGludWVcbiAgICBjb25zdCBmb3VuZCA9IGZpbmRUYXNrMDM0Tm9kZShjaGlsZCwgc2VlbilcbiAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZFxuICB9XG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBGaW5kcyBvbmUgdXNlciBkZWNsYXJhdGlvbiB0aGF0IHdvdWxkIGNvbGxpZGUgd2l0aCB0aGUgcHJvdGVjdGVkIHN1cHBvcnQgc3VyZmFjZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFZhbGlkYXRlZCBzZW1hbnRpYyBncmFwaC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7cmVhZG9ubHkgc3RyaW5nW119IFt1c2VkT3BlcmF0aW9uc10gLSBMaW5rZWQgcHJvdmlkZXIgb3BlcmF0aW9uczsgb21pdHRlZCBmb3IgdGhlIGZ1bGwgaW5saW5lZCBzdXJmYWNlLlxuICogQHJldHVybnMge3tuYW1lOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gfCB1bmRlZmluZWR9IEZpcnN0IGNvbGxpc2lvbi5cbiAqL1xuZnVuY3Rpb24gZmluZFN1cHBvcnRDb2xsaXNpb24obW9kdWxlLCBsYW5ndWFnZSwgdXNlZE9wZXJhdGlvbnMpIHtcbiAgY29uc3QgcmVzZXJ2ZWQgPSBuZXcgU2V0KClcblxuICBpZiAodXNlZE9wZXJhdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBwcm90ZWN0ZWRTdXBwb3J0TmFtZXMpIHJlc2VydmVkLmFkZChzdXBwb3J0TmFtZUtleShuYW1lLCBsYW5ndWFnZSkpXG4gICAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiKSB7XG4gICAgICByZXNlcnZlZC5hZGQoXCJfX3NlbWFudGlmb2xkVGFzazAzNEZzXCIpXG4gICAgICByZXNlcnZlZC5hZGQoXCJfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlXCIpXG4gICAgfSBlbHNlIGlmIChsYW5ndWFnZSA9PSBcInBocFwiKSByZXNlcnZlZC5hZGQoXCJfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2VcIilcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB1c2VkID0gbmV3IFNldCh1c2VkT3BlcmF0aW9ucylcblxuICAgIGZvciAoY29uc3QgbmFtZSBvZiB1c2VkKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkobmFtZSwgbGFuZ3VhZ2UpKVxuICAgIGlmICh1c2VkLmhhcyhcInByb2JlRWZmZWN0XCIpKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkoXCJQcm9iZU9wZXJhdGlvbkZhaWx1cmVcIiwgbGFuZ3VhZ2UpKVxuICAgIGlmICh1c2VkLmhhcyhcInByb2JlQWNxdWlyZVwiKSkgcmVzZXJ2ZWQuYWRkKHN1cHBvcnROYW1lS2V5KFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiLCBsYW5ndWFnZSkpXG4gICAgaWYgKHVzZWQuaGFzKFwicHJvYmVSZWFkXCIpKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkoXCJQcm9iZVJlYWRGYWlsdXJlXCIsIGxhbmd1YWdlKSlcbiAgICBpZiAodXNlZC5oYXMoXCJwcm9iZUNsb3NlXCIpKSByZXNlcnZlZC5hZGQoc3VwcG9ydE5hbWVLZXkoXCJQcm9iZUNsb3NlRmFpbHVyZVwiLCBsYW5ndWFnZSkpXG4gICAgaWYgKHVzZWQuaGFzKFwicHJvYmVSZWFkXCIpIHx8IHVzZWQuaGFzKFwicHJvYmVDbG9zZVwiKSkgcmVzZXJ2ZWQuYWRkKHN1cHBvcnROYW1lS2V5KFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiLCBsYW5ndWFnZSkpXG4gICAgaWYgKHVzZWQuaGFzKFwicHJvYmVBY3F1aXJlXCIpIHx8IHVzZWQuaGFzKFwicHJvYmVSZWFkXCIpIHx8IHVzZWQuaGFzKFwicHJvYmVDbG9zZVwiKSkge1xuICAgICAgcmVzZXJ2ZWQuYWRkKHN1cHBvcnROYW1lS2V5KFwiUHJvYmVSZXNvdXJjZVwiLCBsYW5ndWFnZSkpXG4gICAgfVxuICAgIGlmICh1c2VkLnNpemUgPiAwKSB7XG4gICAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIpIHtcbiAgICAgICAgcmVzZXJ2ZWQuYWRkKFwiX19zZW1hbnRpZm9sZFRhc2swMzRUcmFjZVwiKVxuICAgICAgICBpZiAodXNlZC5oYXMoXCJwcm9iZUFjcXVpcmVcIikpIHJlc2VydmVkLmFkZChcIl9fc2VtYW50aWZvbGRUYXNrMDM0RnNcIilcbiAgICAgIH0gZWxzZSBpZiAobGFuZ3VhZ2UgPT0gXCJwaHBcIikgcmVzZXJ2ZWQuYWRkKFwiX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlXCIpXG4gICAgfVxuICB9XG4gIGNvbnN0IGRlY2xhcmF0aW9ucyA9IFsuLi5tb2R1bGUucmVjb3JkcyA/PyBbXSwgLi4ubW9kdWxlLmNsYXNzZXMgPz8gW10sIC4uLm1vZHVsZS5lcnJvcnMgPz8gW10sIC4uLm1vZHVsZS5mdW5jdGlvbnNdXG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBkZWNsYXJhdGlvbnMpIHtcbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgIGlmIChyZXNlcnZlZC5oYXMoc3VwcG9ydE5hbWVLZXkoZGVjbGFyYXRpb24ubmFtZSwgbGFuZ3VhZ2UpKSkgcmV0dXJuIHtsb2NhdGlvbjogZGVjbGFyYXRpb24ubG9jYXRpb24sIG5hbWU6IGRlY2xhcmF0aW9uLm5hbWV9XG4gIH1cbiAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwicGhwXCIpIHtcbiAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBtb2R1bGUuZW50cnlQb2ludC5ib2R5LnN0YXRlbWVudHMpIHtcbiAgICAgIGlmICghc3RhdGVtZW50IHx8IHR5cGVvZiBzdGF0ZW1lbnQgIT0gXCJvYmplY3RcIikgY29udGludWVcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiAmJiByZXNlcnZlZC5oYXMoc3VwcG9ydE5hbWVLZXkoc3RhdGVtZW50Lm5hbWUsIGxhbmd1YWdlKSkpIHtcbiAgICAgICAgcmV0dXJuIHtsb2NhdGlvbjogc3RhdGVtZW50LmxvY2F0aW9uLCBuYW1lOiBzdGF0ZW1lbnQubmFtZX1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEFwcGxpZXMgdGFyZ2V0IG5hbWVzcGFjZSBjYXNpbmcgdG8gYSBwcm90ZWN0ZWQgc3VwcG9ydCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBTb3VyY2UgbmFtZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IENvbXBhcmFibGUgbmFtZS5cbiAqL1xuZnVuY3Rpb24gc3VwcG9ydE5hbWVLZXkobmFtZSwgbGFuZ3VhZ2UpIHtcbiAgcmV0dXJuIGxhbmd1YWdlID09IFwicGhwXCIgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOiBuYW1lXG59XG5cbi8qKlxuICogRW1pdHMgZml4ZWQgdGFyZ2V0LXByaXZhdGUgVGFzayAwMzQgY29uZm9ybWFuY2Ugc3VwcG9ydC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBEZXN0aW5hdGlvbiB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBBdXRob3JpemVkIG1vZHVsZS5cbiAqIEBwYXJhbSB7XCJwaHBcIiB8IFwicnVieVwiIHwgXCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIiB8IFwiamF2YVwifSBsYW5ndWFnZSAtIEFkb3B0ZWQgdGFyZ2V0LlxuICogQHBhcmFtIHtcInRvcFwiIHwgXCJtZW1iZXJzXCJ9IFtwbGFjZW1lbnRdIC0gSmF2YSBzdXBwb3J0IHBsYWNlbWVudC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZW1pdEVmZmVjdFN1cHBvcnQod3JpdGVyLCBtb2R1bGUsIGxhbmd1YWdlLCBwbGFjZW1lbnQgPSBcInRvcFwiKSB7XG4gIGNvbnN0IGxpbmtlZCA9IHdyaXRlci5zdGRsaWJQcm92aWRlckVudHJpZXMgIT09IHVuZGVmaW5lZFxuXG4gIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIiAmJiBsaW5rZWQpIHtcbiAgICBpZiAocGxhY2VtZW50ICE9IFwibWVtYmVyc1wiIHx8IHdyaXRlci5zdGRsaWJQcm92aWRlclNoaW1zID09PSB1bmRlZmluZWQpIHJldHVyblxuICB9IGVsc2UgaWYgKGxpbmtlZCB8fCAhbW9kdWxlLmNhcGFiaWxpdGllcyB8fCAhbW9kdWxlTmVlZHNFZmZlY3RTdXBwb3J0KG1vZHVsZSkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBjb250ZW50ID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IHBocFN1cHBvcnQgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IHJ1YnlTdXBwb3J0IDogbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgPyBqYXZhc2NyaXB0U3VwcG9ydCA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyB0eXBlc2NyaXB0U3VwcG9ydCA6XG4gICAgd3JpdGVyLnN0ZGxpYlByb3ZpZGVyU2hpbXMgIT09IHVuZGVmaW5lZCA/IGphdmFQcm9ncmFtTmVzdGVkU3VwcG9ydCArIGphdmFNZW1iZXJTdXBwb3J0IDpcbiAgICBwbGFjZW1lbnQgPT0gXCJ0b3BcIiA/IGphdmFUb3BTdXBwb3J0IDogamF2YU1lbWJlclN1cHBvcnRcblxuICB3cml0ZXIuc3ludGhldGljKGNvbnRlbnQsIFwic2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0XCIsIFttb2R1bGVdKVxufVxuXG4vKipcbiAqIEVtaXRzIHRoZSBwdWJsaWMgc3RhdGljIHByb3ZpZGVyIHNoaW1zIGZvciB0aGUgcHJvZ3JhbS13aWRlIHVzZWQgb3BlcmF0aW9ucyBvbiB0aGUgSmF2YSBvd25lciBtb2R1bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gRGVzdGluYXRpb24gd3JpdGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gT3duZXIgbW9kdWxlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0RWZmZWN0UHJvdmlkZXJFbnRyaWVzKHdyaXRlciwgbW9kdWxlKSB7XG4gIGNvbnN0IG9wZXJhdGlvbnMgPSB3cml0ZXIuc3RkbGliUHJvdmlkZXJTaGltcyA/PyBbXVxuXG4gIGlmIChvcGVyYXRpb25zLmxlbmd0aCA9PSAwKSByZXR1cm5cbiAgY29uc3QgbGluZXMgPSBvcGVyYXRpb25zLm1hcCgob3BlcmF0aW9uKSA9PiBgICAke2phdmFQcm92aWRlclNoaW1zW29wZXJhdGlvbl19YClcblxuICB3cml0ZXIuc3ludGhldGljKGAke2xpbmVzLmpvaW4oXCJcXG5cIil9XFxuXFxuYCwgXCJzZW1hbnRpZm9sZC1zdGRsaWItcHJvdmlkZXItZW50cmllc1wiLCBbbW9kdWxlXSlcbn1cblxuLyoqXG4gKiBSZWNvZ25pemVzIG9ubHkgdGhlIGJ5dGUtZXhhY3QgcHJvdGVjdGVkIHN1cHBvcnQgZW1pdHRlZCBieSB0aGlzIGJhY2tlbmQuXG4gKiBGcm9udGVuZHMgdXNlIHRoaXMgaW4gYWRkaXRpb24gdG8gcGFyc2VyLXNoYXBlIGNoZWNrcyBkdXJpbmcgZ2VuZXJhdGVkLXNvdXJjZSByZXBhcnNlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIGNhbmRpZGF0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1wicGhwXCIgfCBcInJ1YnlcIiB8IFwiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCIgfCBcImphdmFcIn0gbGFuZ3VhZ2UgLSBBZG9wdGVkIHRhcmdldC5cbiAqIEBwYXJhbSB7XCJ0b3BcIiB8IFwibWVtYmVyc1wifSBbcGxhY2VtZW50XSAtIEphdmEgc3VwcG9ydCBwbGFjZW1lbnQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZXhhY3QgcHJvdGVjdGVkIHNlZ21lbnQgaXMgcHJlc2VudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc0V4YWN0RWZmZWN0U3VwcG9ydChzb3VyY2UsIGxhbmd1YWdlLCBwbGFjZW1lbnQgPSBcInRvcFwiKSB7XG4gIGNvbnN0IGNvbnRlbnQgPSBsYW5ndWFnZSA9PSBcInBocFwiID8gcGhwU3VwcG9ydCA6IGxhbmd1YWdlID09IFwicnVieVwiID8gcnVieVN1cHBvcnQgOiBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiA/IGphdmFzY3JpcHRTdXBwb3J0IDpcbiAgICBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiA/IHR5cGVzY3JpcHRTdXBwb3J0IDogcGxhY2VtZW50ID09IFwidG9wXCIgPyBqYXZhVG9wU3VwcG9ydCA6IGphdmFNZW1iZXJTdXBwb3J0XG5cbiAgcmV0dXJuIHNvdXJjZS5pbmNsdWRlcyhjb250ZW50KVxufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplcyBuZXN0ZWQgZWZmZWN0IHNpdGVzIGJlZm9yZSB0aGVpciBlbmNsb3NpbmcgZWFnZXIgZXhwcmVzc2lvbi5cbiAqIFRoZSBpbnN0YWxsZWQgcmVwbGFjZW1lbnRzIHJlbWFpbiBhY3RpdmUgdW50aWwgdGhlIG5leHQgc3RhdGVtZW50IGJlZ2lucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBEZXN0aW5hdGlvbiB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gc3RhdGVtZW50IC0gQ3VycmVudCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5kZW50IC0gQ3VycmVudCB0YXJnZXQgaW5kZW50YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIEV4YWN0IHN0YXRlbWVudCBwYXRoLlxuICogQHBhcmFtIHtcInBocFwiIHwgXCJydWJ5XCIgfCBcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwiIHwgXCJqYXZhXCJ9IGxhbmd1YWdlIC0gQWRvcHRlZCB0YXJnZXQuXG4gKiBAcGFyYW0geyhleHByZXNzaW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9uLCBwYXRoOiBzdHJpbmcpID0+IHZvaWR9IGVtaXQgLSBUYXJnZXQgZXhwcmVzc2lvbiBlbWl0dGVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0RWZmZWN0UHJlZml4ZXMod3JpdGVyLCBzdGF0ZW1lbnQsIGluZGVudCwgcGF0aCwgbGFuZ3VhZ2UsIGVtaXQpIHtcbiAgLyoqIEB0eXBlIHtFeHByZXNzaW9uUGF0aFtdfSAqL1xuICBjb25zdCBwbGFubmVkID0gW11cblxuICBmb3IgKGNvbnN0IHJvb3Qgb2Ygc3RhdGVtZW50RXhwcmVzc2lvblJvb3RzKHN0YXRlbWVudCwgcGF0aCkpIGNvbGxlY3ROZXN0ZWRFZmZlY3RzKHJvb3QuZXhwcmVzc2lvbiwgcm9vdC5wYXRoLCByb290LmV4cHJlc3Npb24sIHBsYW5uZWQpXG4gIHdyaXRlci5wbGFuRWZmZWN0UmVwbGFjZW1lbnRzKHBsYW5uZWQubWFwKCh7ZXhwcmVzc2lvbn0pID0+IGV4cHJlc3Npb24pKVxuICBmb3IgKGNvbnN0IHtleHByZXNzaW9uLCBwYXRoOiBleHByZXNzaW9uUGF0aH0gb2YgcGxhbm5lZCkge1xuICAgIGNvbnN0IG5hbWUgPSB3cml0ZXIuZWZmZWN0VGVtcG9yYXJ5TmFtZShleHByZXNzaW9uKVxuICAgIGNvbnN0IHR5cGUgPSBlZmZlY3RFeHByZXNzaW9uVHlwZSh3cml0ZXIsIGV4cHJlc3Npb24pXG4gICAgY29uc3QgdHlwZU5hbWUgPSBlbWl0dGVkVHlwZU5hbWUod3JpdGVyLCB0eXBlLCBsYW5ndWFnZSlcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGxhbmd1YWdlID09IFwicGhwXCJcbiAgICAgID8gYC8qKlxcbiR7aW5kZW50fSAqIEB2YXIgJHt0eXBlTmFtZX0gJCR7bmFtZX1cXG4ke2luZGVudH0gKiBAc2VtYW50aWZvbGQtaW1tdXRhYmxlXFxuJHtpbmRlbnR9ICovXFxuJHtpbmRlbnR9JCR7bmFtZX0gPSBgXG4gICAgICA6IGxhbmd1YWdlID09IFwicnVieVwiXG4gICAgICAgID8gYCMgQHR5cGUgWyR7dHlwZU5hbWV9XVxcbiR7aW5kZW50fSMgQHNlbWFudGlmb2xkLWltbXV0YWJsZVxcbiR7aW5kZW50fSR7bmFtZX0gPSBgXG4gICAgICAgIDogbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgPyBgLyoqIEB0eXBlIHske3R5cGVOYW1lfX0gKi9cXG4ke2luZGVudH1jb25zdCAke25hbWV9ID0gYFxuICAgICAgICAgIDogbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyBgY29uc3QgJHtuYW1lfTogJHt0eXBlTmFtZX0gPSBgIDogYGZpbmFsICR7dHlwZU5hbWV9ICR7bmFtZX0gPSBgXG5cbiAgICB3cml0ZXIuc3ludGhldGljKGAke2luZGVudH0ke2RlY2xhcmF0aW9ufWAsIFwiZXhhY3RseS1vbmNlIGVmZmVjdCB0ZW1wb3JhcnlcIiwgW2V4cHJlc3Npb25dLCBbZXhwcmVzc2lvblBhdGhdKVxuICAgIHdyaXRlci5lbWl0RWZmZWN0RGVmaW5pdGlvbihleHByZXNzaW9uLCAoKSA9PiBlbWl0KGV4cHJlc3Npb24sIGV4cHJlc3Npb25QYXRoKSlcbiAgICB3cml0ZXIuc3ludGhldGljKGxhbmd1YWdlID09IFwicnVieVwiID8gXCJcXG5cIiA6IFwiO1xcblwiLCBcImV4YWN0bHktb25jZSBlZmZlY3QgdGVtcG9yYXJ5IHRlcm1pbmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbZXhwcmVzc2lvblBhdGhdKVxuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIHJlc3VsdCB0eXBlIG5lZWRlZCBmb3IgYW4gZWZmZWN0IHRlbXBvcmFyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBBY3RpdmUgd3JpdGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gRWZmZWN0ZnVsIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGUgfCB1bmRlZmluZWR9IFJlc3VsdCB0eXBlLlxuICovXG5mdW5jdGlvbiBlZmZlY3RFeHByZXNzaW9uVHlwZSh3cml0ZXIsIGV4cHJlc3Npb24pIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIpIHJldHVybiB3cml0ZXIuZWZmZWN0T3BlcmF0aW9uRm9ySWQoZXhwcmVzc2lvbi5vcGVyYXRpb24pLnJldHVyblR5cGVcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uLnJlc29sdXRpb24gPyBzZW1hbnRpY1R5cGVGb3JJZGVudGl0eShleHByZXNzaW9uLnJlc29sdXRpb24ucmV0dXJuVHlwZSkgOiB1bmRlZmluZWRcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogUmVoeWRyYXRlcyBhIHJlc29sdmVkIGNhbGwgcmVzdWx0IGZvciB0YXJnZXQtbG9jYWwgdGVtcG9yYXJ5IHNwZWxsaW5nLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvblJldHVyblR5cGVJZGVudGl0eX0gaWRlbnRpdHkgLSBFeGFjdCByZXNvbHZlZCByZXN1bHQgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IERldGFjaGVkIHNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIHNlbWFudGljVHlwZUZvcklkZW50aXR5KGlkZW50aXR5KSB7XG4gIGlmICh0eXBlb2YgaWRlbnRpdHkgPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiB7a2luZDogXCJUeXBlUmVmZXJlbmNlXCIsIG5hbWU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25SZXR1cm5UeXBlTmFtZX0gKi8gKGlkZW50aXR5KX1cbiAgfVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIkxpc3RUeXBlXCIpIHJldHVybiB7ZWxlbWVudFR5cGU6IHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkuZWxlbWVudFR5cGUpLCBraW5kOiBcIkxpc3RUeXBlXCJ9XG4gIGlmIChpZGVudGl0eS5raW5kID09IFwiTWFwVHlwZVwiKSByZXR1cm4ge2tleVR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKFxuICAgIHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkua2V5VHlwZSkpLCBraW5kOiBcIk1hcFR5cGVcIixcbiAgICB2YWx1ZVR5cGU6IHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkudmFsdWVUeXBlKX1cbiAgaWYgKGlkZW50aXR5LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSByZXR1cm4ge2tleVR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKFxuICAgIHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkua2V5VHlwZSkpLCBraW5kOiBcIk9yZGVyZWRNYXBUeXBlXCIsXG4gICAgb3JkZXI6IFwiaW5zZXJ0aW9uXCIsIHZhbHVlVHlwZTogc2VtYW50aWNUeXBlRm9yVmFsdWVJZGVudGl0eShpZGVudGl0eS52YWx1ZVR5cGUpfVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSByZXR1cm4ge2tpbmQ6IFwiT3B0aW9uYWxUeXBlXCIsIHZhbHVlVHlwZTogc2VtYW50aWNUeXBlRm9yVmFsdWVJZGVudGl0eShpZGVudGl0eS52YWx1ZVR5cGUpfVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIlJlY29yZFR5cGVcIikgcmV0dXJuIHthcmd1bWVudHM6IGlkZW50aXR5LmFyZ3VtZW50cz8ubWFwKHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkpLFxuICAgIGRlY2xhcmF0aW9uSWQ6IGlkZW50aXR5LmRlY2xhcmF0aW9uSWQsIGtpbmQ6IFwiUmVjb3JkVHlwZVwifVxuICBpZiAoaWRlbnRpdHkua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIHtkZWNsYXJhdGlvbklkOiBpZGVudGl0eS5kZWNsYXJhdGlvbklkLCBraW5kOiBcIlJlZmVyZW5jZVR5cGVcIn1cbiAgaWYgKGlkZW50aXR5LmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSByZXR1cm4ge2tpbmQ6IFwiT3duZWRSZXNvdXJjZVR5cGVcIiwgcmVzb3VyY2VJZDogaWRlbnRpdHkucmVzb3VyY2VJZH1cbiAgaWYgKGlkZW50aXR5LmtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIHtkZWNsYXJhdGlvbklkOiBpZGVudGl0eS5kZWNsYXJhdGlvbklkLCBraW5kOiBcIk93bmVkUmVmZXJlbmNlVHlwZVwifVxuICByZXR1cm4ge2tpbmQ6IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIsIGxvY2F0aW9uOiAvKiogQHR5cGUge25ldmVyfSAqLyAodW5kZWZpbmVkKSwgcGFyYW1ldGVySWQ6IGlkZW50aXR5LnBhcmFtZXRlcklkfVxufVxuXG4vKipcbiAqIFJlaHlkcmF0ZXMgb25lIG5vbi12b2lkIHJlc29sdmVkIHR5cGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZUlkZW50aXR5fSBpZGVudGl0eSAtIEV4YWN0IHR5cGUgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IERldGFjaGVkIHNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIHNlbWFudGljVHlwZUZvclZhbHVlSWRlbnRpdHkoaWRlbnRpdHkpIHtcbiAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9ICovIChzZW1hbnRpY1R5cGVGb3JJZGVudGl0eShpZGVudGl0eSkpXG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgc3Vic2V0IG9mIHNlbWFudGljIHR5cGVzIGFkbWl0dGVkIGZvciBzeW50aGV0aWMgdGVtcG9yYXJpZXMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gQWN0aXZlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGUgfCB1bmRlZmluZWR9IHR5cGUgLSBTZW1hbnRpYyB0eXBlLlxuICogQHBhcmFtIHtcInBocFwiIHwgXCJydWJ5XCIgfCBcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwiIHwgXCJqYXZhXCJ9IGxhbmd1YWdlIC0gVGFyZ2V0LlxuICogQHBhcmFtIHtib29sZWFufSBbbmVzdGVkXSAtIFdoZXRoZXIgSmF2YSByZXF1aXJlcyBhIGJveGVkIHNjYWxhci5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRhcmdldCB0eXBlIHNwZWxsaW5nLlxuICovXG5mdW5jdGlvbiBlbWl0dGVkVHlwZU5hbWUod3JpdGVyLCB0eXBlLCBsYW5ndWFnZSwgbmVzdGVkID0gZmFsc2UpIHtcbiAgaWYgKCF0eXBlIHx8IHR5cGUua2luZCA9PSBcIlR5cGVSZWZlcmVuY2VcIiAmJiB0eXBlLm5hbWUgPT0gXCJ2b2lkXCIpIHJldHVybiBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiT2JqZWN0XCIgOiBcInVua25vd25cIlxuICBpZiAodHlwZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiKSB7XG4gICAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIpIHJldHVybiB0eXBlLm5hbWUgPT0gXCJpbnRlZ2VyXCIgPyBcImludFwiIDogdHlwZS5uYW1lID09IFwiYm9vbGVhblwiID8gXCJib29sXCIgOiBcInN0cmluZ1wiXG4gICAgaWYgKGxhbmd1YWdlID09IFwicnVieVwiKSByZXR1cm4gdHlwZS5uYW1lID09IFwiaW50ZWdlclwiID8gXCJJbnRlZ2VyXCIgOiB0eXBlLm5hbWUgPT0gXCJib29sZWFuXCIgPyBcIkJvb2xlYW5cIiA6IFwiU3RyaW5nXCJcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHJldHVybiB0eXBlLm5hbWUgPT0gXCJpbnRlZ2VyXCIgPyBuZXN0ZWQgPyBcIkludGVnZXJcIiA6IFwiaW50XCIgOlxuICAgICAgdHlwZS5uYW1lID09IFwiYm9vbGVhblwiID8gbmVzdGVkID8gXCJCb29sZWFuXCIgOiBcImJvb2xlYW5cIiA6IFwiU3RyaW5nXCJcbiAgICByZXR1cm4gdHlwZS5uYW1lID09IFwiaW50ZWdlclwiID8gXCJudW1iZXJcIiA6IHR5cGUubmFtZVxuICB9XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSByZXR1cm4gd3JpdGVyLnJlc291cmNlRm9ySWQodHlwZS5yZXNvdXJjZUlkKS5uYW1lXG4gIGlmICh0eXBlLmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIgfHwgdHlwZS5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHJldHVybiB3cml0ZXIuY2xhc3NOYW1lRm9ySWQodHlwZS5kZWNsYXJhdGlvbklkKVxuICBpZiAodHlwZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHJldHVybiB3cml0ZXIudHlwZVBhcmFtZXRlckZvcklkKHR5cGUucGFyYW1ldGVySWQpLm5hbWVcbiAgaWYgKHR5cGUua2luZCA9PSBcIlJlY29yZFR5cGVcIikge1xuICAgIGNvbnN0IG5hbWUgPSB3cml0ZXIucmVjb3JkTmFtZUZvcklkKHR5cGUuZGVjbGFyYXRpb25JZClcbiAgICBjb25zdCBhcmd1bWVudHNfID0gdHlwZS5hcmd1bWVudHM/Lm1hcCgoYXJndW1lbnQpID0+IGVtaXR0ZWRUeXBlTmFtZSh3cml0ZXIsIGFyZ3VtZW50LCBsYW5ndWFnZSwgdHJ1ZSkpID8/IFtdXG5cbiAgICByZXR1cm4gYXJndW1lbnRzXy5sZW5ndGggPT0gMCA/IG5hbWUgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IGAke25hbWV9WyR7YXJndW1lbnRzXy5qb2luKFwiLFwiKX1dYCA6IGAke25hbWV9PCR7YXJndW1lbnRzXy5qb2luKFwiLFwiKX0+YFxuICB9XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgIGNvbnN0IHZhbHVlID0gZW1pdHRlZFR5cGVOYW1lKHdyaXRlciwgdHlwZS52YWx1ZVR5cGUsIGxhbmd1YWdlLCB0cnVlKVxuICAgIHJldHVybiBsYW5ndWFnZSA9PSBcInBocFwiID8gYD8ke3ZhbHVlfWAgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IGAke3ZhbHVlfT9gIDpcbiAgICAgIGxhbmd1YWdlID09IFwiamF2YVwiID8gYGphdmEudXRpbC5PcHRpb25hbDwke3ZhbHVlfT5gIDogYCR7dmFsdWV9IHwgbnVsbGBcbiAgfVxuICBpZiAodHlwZS5raW5kID09IFwiTGlzdFR5cGVcIikge1xuICAgIGNvbnN0IHZhbHVlID0gZW1pdHRlZFR5cGVOYW1lKHdyaXRlciwgdHlwZS5lbGVtZW50VHlwZSwgbGFuZ3VhZ2UsIHRydWUpXG4gICAgcmV0dXJuIGxhbmd1YWdlID09IFwicGhwXCIgPyBgbGlzdDwke3ZhbHVlfT5gIDogbGFuZ3VhZ2UgPT0gXCJydWJ5XCIgPyBgQXJyYXk8JHt2YWx1ZX0+YCA6XG4gICAgICBsYW5ndWFnZSA9PSBcImphdmFcIiA/IGBqYXZhLnV0aWwuTGlzdDwke3ZhbHVlfT5gIDogYHJlYWRvbmx5ICR7dmFsdWV9W11gXG4gIH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIk1hcFR5cGVcIiB8fCB0eXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgY29uc3Qga2V5ID0gZW1pdHRlZFR5cGVOYW1lKHdyaXRlciwgdHlwZS5rZXlUeXBlLCBsYW5ndWFnZSwgdHJ1ZSlcbiAgICBjb25zdCB2YWx1ZSA9IGVtaXR0ZWRUeXBlTmFtZSh3cml0ZXIsIHR5cGUudmFsdWVUeXBlLCBsYW5ndWFnZSwgdHJ1ZSlcblxuICAgIGlmIChsYW5ndWFnZSA9PSBcInBocFwiKSByZXR1cm4gYGFycmF5PCR7a2V5fSwke3ZhbHVlfT5gXG4gICAgaWYgKGxhbmd1YWdlID09IFwicnVieVwiKSByZXR1cm4gYEhhc2hbJHtrZXl9LCR7dmFsdWV9XWBcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHJldHVybiBgJHt0eXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJqYXZhLnV0aWwuU2VxdWVuY2VkTWFwXCIgOiBcImphdmEudXRpbC5NYXBcIn08JHtrZXl9LCR7dmFsdWV9PmBcbiAgICByZXR1cm4gYFJlYWRvbmx5TWFwPCR7a2V5fSwgJHt2YWx1ZX0+YFxuICB9XG4gIHJldHVybiBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiT2JqZWN0XCIgOiBcInVua25vd25cIlxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gcm9vdHMgZXZhbHVhdGVkIGJ5IG9uZSBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gc3RhdGVtZW50IC0gU3RhdGVtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBTdGFibGUgc3RhdGVtZW50IHBhdGguXG4gKiBAcmV0dXJucyB7RXhwcmVzc2lvblBhdGhbXX0gRXhwcmVzc2lvbiByb290cy5cbiAqL1xuZnVuY3Rpb24gc3RhdGVtZW50RXhwcmVzc2lvblJvb3RzKHN0YXRlbWVudCwgcGF0aCkge1xuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIHJldHVybiBbe2V4cHJlc3Npb246IHN0YXRlbWVudC5pbml0aWFsaXplciwgcGF0aDogYCR7cGF0aH0vaW5pdGlhbGl6ZXJgfV1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgIHJldHVybiBbe2V4cHJlc3Npb246IHN0YXRlbWVudC5leHByZXNzaW9uLCBwYXRoOiBgJHtwYXRofS9leHByZXNzaW9uYH1dXG4gIH1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIpIHJldHVybiBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA/IFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50LmV4cHJlc3Npb24sIHBhdGg6IGAke3BhdGh9L2V4cHJlc3Npb25gfV0gOiBbXVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiKSByZXR1cm4gW3tleHByZXNzaW9uOiBzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgcGF0aDogYCR7cGF0aH0vZXhwcmVzc2lvbmB9XVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIikgcmV0dXJuIFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50LmNvbmRpdGlvbiwgcGF0aDogYCR7cGF0aH0vY29uZGl0aW9uYH1dXG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIikgcmV0dXJuIFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50Lmxpc3QsIHBhdGg6IGAke3BhdGh9L2xpc3RgfV1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSByZXR1cm4gW3tleHByZXNzaW9uOiBzdGF0ZW1lbnQubWFwLCBwYXRoOiBgJHtwYXRofS9tYXBgfV1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmFpc2VTdGF0ZW1lbnRcIikgcmV0dXJuIFt7ZXhwcmVzc2lvbjogc3RhdGVtZW50LmVycm9yLm1lc3NhZ2UsIHBhdGg6IGAke3BhdGh9L2Vycm9yL21lc3NhZ2VgfV1cbiAgcmV0dXJuIFtdXG59XG5cbi8qKlxuICogQ29sbGVjdHMgbmVzdGVkIGVmZmVjdCBzaXRlcyBpbiBwb3N0b3JkZXIgc28gY2hpbGRyZW4gYXJlIG1hdGVyaWFsaXplZCBmaXJzdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIEN1cnJlbnQgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gQ3VycmVudCBvY2N1cnJlbmNlIHBhdGguXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IHJvb3QgLSBTdGF0ZW1lbnQgZXhwcmVzc2lvbiByb290LlxuICogQHBhcmFtIHtFeHByZXNzaW9uUGF0aFtdfSBvdXRwdXQgLSBPcmRlcmVkIHBsYW4gcmVjZWl2aW5nIG5lc3RlZCBzaXRlcy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBjb2xsZWN0TmVzdGVkRWZmZWN0cyhleHByZXNzaW9uLCBwYXRoLCByb290LCBvdXRwdXQpIHtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBleHByZXNzaW9uQ2hpbGRyZW4oZXhwcmVzc2lvbiwgcGF0aCkpIGNvbGxlY3ROZXN0ZWRFZmZlY3RzKGNoaWxkLmV4cHJlc3Npb24sIGNoaWxkLnBhdGgsIHJvb3QsIG91dHB1dClcbiAgaWYgKGV4cHJlc3Npb24gIT09IHJvb3QgJiYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgfHwgdHlwZW9mIFJlZmxlY3QuZ2V0KGV4cHJlc3Npb24sIFwiZWZmZWN0U2l0ZUlkXCIpID09IFwic3RyaW5nXCIpKSB7XG4gICAgb3V0cHV0LnB1c2goe2V4cHJlc3Npb24sIHBhdGh9KVxuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBwYXRoLWJlYXJpbmcgZXhwcmVzc2lvbiBjaGlsZHJlbiBpbiBldmFsdWF0aW9uIG9yZGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gUGFyZW50IGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIFBhcmVudCBwYXRoLlxuICogQHJldHVybnMge0V4cHJlc3Npb25QYXRoW119IENoaWxkcmVuLlxuICovXG5mdW5jdGlvbiBleHByZXNzaW9uQ2hpbGRyZW4oZXhwcmVzc2lvbiwgcGF0aCkge1xuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiIHx8XG4gICAgZXhwcmVzc2lvbi5raW5kID09IFwiUmVjb3JkQ29uc3RydWN0aW9uXCIpIHJldHVybiBleHByZXNzaW9uLmFyZ3VtZW50cy5tYXAoKGNoaWxkLCBpbmRleCkgPT4gKHtleHByZXNzaW9uOiBjaGlsZCwgcGF0aDogYCR7cGF0aH0vYXJndW1lbnRzLyR7aW5kZXh9YH0pKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIikgcmV0dXJuIFtcbiAgICB7ZXhwcmVzc2lvbjogZXhwcmVzc2lvbi5yZWNlaXZlciwgcGF0aDogYCR7cGF0aH0vcmVjZWl2ZXJgfSxcbiAgICAuLi5leHByZXNzaW9uLmFyZ3VtZW50cy5tYXAoKGNoaWxkLCBpbmRleCkgPT4gKHtleHByZXNzaW9uOiBjaGlsZCwgcGF0aDogYCR7cGF0aH0vYXJndW1lbnRzLyR7aW5kZXh9YH0pKVxuICBdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIHtcbiAgICByZXR1cm4gW3tleHByZXNzaW9uOiBleHByZXNzaW9uLmV4cHJlc3Npb24sIHBhdGg6IGAke3BhdGh9L2V4cHJlc3Npb25gfV1cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gW1xuICAgIHtleHByZXNzaW9uOiBleHByZXNzaW9uLmxlZnQsIHBhdGg6IGAke3BhdGh9L2xlZnRgfSwge2V4cHJlc3Npb246IGV4cHJlc3Npb24ucmlnaHQsIHBhdGg6IGAke3BhdGh9L3JpZ2h0YH1cbiAgXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiVW5hcnlFeHByZXNzaW9uXCIpIHJldHVybiBbe2V4cHJlc3Npb246IGV4cHJlc3Npb24ub3BlcmFuZCwgcGF0aDogYCR7cGF0aH0vb3BlcmFuZGB9XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxTb21lXCIpIHJldHVybiBbe2V4cHJlc3Npb246IGV4cHJlc3Npb24udmFsdWUsIHBhdGg6IGAke3BhdGh9L3ZhbHVlYH1dXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbElzUHJlc2VudFwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsVW53cmFwXCIpIHtcbiAgICByZXR1cm4gW3tleHByZXNzaW9uOiBleHByZXNzaW9uLm9wZXJhbmQsIHBhdGg6IGAke3BhdGh9L29wZXJhbmRgfV1cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdExpdGVyYWxcIikgcmV0dXJuIGV4cHJlc3Npb24uZWxlbWVudHMubWFwKChjaGlsZCwgaW5kZXgpID0+ICh7ZXhwcmVzc2lvbjogY2hpbGQsIHBhdGg6IGAke3BhdGh9L2VsZW1lbnRzLyR7aW5kZXh9YH0pKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWFwTGl0ZXJhbFwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIk9yZGVyZWRNYXBMaXRlcmFsXCIpIHJldHVybiBleHByZXNzaW9uLmVudHJpZXMuZmxhdE1hcCgoZW50cnksIGluZGV4KSA9PiBbXG4gICAge2V4cHJlc3Npb246IGVudHJ5LmtleSwgcGF0aDogYCR7cGF0aH0vZW50cmllcy8ke2luZGV4fS9rZXlgfSwge2V4cHJlc3Npb246IGVudHJ5LnZhbHVlLCBwYXRoOiBgJHtwYXRofS9lbnRyaWVzLyR7aW5kZXh9L3ZhbHVlYH1cbiAgXSlcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RJbmRleEV4cHJlc3Npb25cIikgcmV0dXJuIFtcbiAgICB7ZXhwcmVzc2lvbjogZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBwYXRoOiBgJHtwYXRofS9jb2xsZWN0aW9uYH0sIHtleHByZXNzaW9uOiBleHByZXNzaW9uLmluZGV4LCBwYXRoOiBgJHtwYXRofS9pbmRleGB9XG4gIF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikgcmV0dXJuIFtcbiAgICB7ZXhwcmVzc2lvbjogZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBwYXRoOiBgJHtwYXRofS9jb2xsZWN0aW9uYH0sIHtleHByZXNzaW9uOiBleHByZXNzaW9uLmtleSwgcGF0aDogYCR7cGF0aH0va2V5YH1cbiAgXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBbe2V4cHJlc3Npb246IGV4cHJlc3Npb24uY29sbGVjdGlvbiwgcGF0aDogYCR7cGF0aH0vY29sbGVjdGlvbmB9XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSByZXR1cm4gW3tleHByZXNzaW9uOiBleHByZXNzaW9uLnJlY2VpdmVyLCBwYXRoOiBgJHtwYXRofS9yZWNlaXZlcmB9XVxuICByZXR1cm4gW11cbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBnZW5lcmF0ZWQgc3VwcG9ydCBpcyByZXF1aXJlZCBieSBhIHNlbWFudGljIGNhcGFiaWxpdHkgbm9kZSBvciB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHByb3RlY3RlZCBiaW5kaW5nIGlzIHJlcXVpcmVkLlxuICovXG5mdW5jdGlvbiBtb2R1bGVOZWVkc0VmZmVjdFN1cHBvcnQobW9kdWxlKSB7XG4gIC8qKiBAdHlwZSB7dW5rbm93bltdfSAqL1xuICBjb25zdCBwZW5kaW5nID0gW21vZHVsZS5lbnRyeVBvaW50LCAuLi5tb2R1bGUuZnVuY3Rpb25zLCAuLi5tb2R1bGUucmVjb3JkcyA/PyBbXSwgLi4ubW9kdWxlLmVycm9ycyA/PyBbXSwgLi4ubW9kdWxlLmNsYXNzZXMgPz8gW11dXG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcblxuICB3aGlsZSAocGVuZGluZy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgdmFsdWUgPSBwZW5kaW5nLnBvcCgpXG5cbiAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgY29udGludWVcbiAgICBzZWVuLmFkZCh2YWx1ZSlcbiAgICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKVxuXG4gICAgaWYgKGtpbmQgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiIHx8IGtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiIHx8IGtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIiB8fFxuICAgICAga2luZCA9PSBcIkVycm9yVHlwZVwiICYmIC9eY2FwYWJpbGl0eTpbMC05XStcXC9mYWlsdXJlOlswLTldKyQvdS50ZXN0KFN0cmluZyhSZWZsZWN0LmdldCh2YWx1ZSwgXCJkZWNsYXJhdGlvbklkXCIpKSkpIHJldHVybiB0cnVlXG4gICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICBpZiAoW1wibG9jYXRpb25cIiwgXCJzb3VyY2VQcm92ZW5hbmNlXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZCkpIHBlbmRpbmcucHVzaCguLi5jaGlsZClcbiAgICAgIGVsc2UgaWYgKGNoaWxkICYmIHR5cGVvZiBjaGlsZCA9PSBcIm9iamVjdFwiKSBwZW5kaW5nLnB1c2goY2hpbGQpXG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG4vKipcbiAqIEZpbmRzIGEgY29udGV4dCBleGNsdWRlZCBmcm9tIGJvdW5kZWQgZWFnZXIgbG93ZXJpbmcuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBTZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7RXhjbHVkZWRFZmZlY3QgfCB1bmRlZmluZWR9IEZpcnN0IGRldGVybWluaXN0aWMgZXhjbHVzaW9uLlxuICovXG5mdW5jdGlvbiBmaW5kRXhjbHVkZWRFZmZlY3RDb250ZXh0KG1vZHVsZSkge1xuICAvKiogQHR5cGUge29iamVjdFtdfSAqL1xuICBjb25zdCBvd25lcnMgPSBbLi4ubW9kdWxlLmZ1bmN0aW9ucy5maWx0ZXIoKG93bmVyKSA9PiBvd25lciAmJiB0eXBlb2Ygb3duZXIgPT0gXCJvYmplY3RcIiksIG1vZHVsZS5lbnRyeVBvaW50XVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmNsYXNzZXMgPz8gW10pIHtcbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgIGlmIChkZWNsYXJhdGlvbi5jb25zdHJ1Y3RvciAmJiB0eXBlb2YgZGVjbGFyYXRpb24uY29uc3RydWN0b3IgPT0gXCJvYmplY3RcIikgb3duZXJzLnB1c2goZGVjbGFyYXRpb24uY29uc3RydWN0b3IpXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24ubWV0aG9kcykpIG93bmVycy5wdXNoKC4uLmRlY2xhcmF0aW9uLm1ldGhvZHMuZmlsdGVyKChvd25lcikgPT4gb3duZXIgJiYgdHlwZW9mIG93bmVyID09IFwib2JqZWN0XCIpKVxuICB9XG4gIGZvciAoY29uc3Qgb3duZXIgb2Ygb3duZXJzKSB7XG4gICAgY29uc3QgYm9keSA9IFJlZmxlY3QuZ2V0KG93bmVyLCBcImJvZHlcIilcblxuICAgIGlmICghYm9keSB8fCB0eXBlb2YgYm9keSAhPSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgIGNvbnN0IGZvdW5kID0gYmxvY2tFeGNsdWRlZCgvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSAqLyAoYm9keSkpXG4gICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogRmluZHMgYW4gZXhjbHVkZWQgY29udGV4dCBpbiBvbmUgc3RydWN0dXJlZCBibG9jay5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gU2VtYW50aWMgYmxvY2suXG4gKiBAcmV0dXJucyB7RXhjbHVkZWRFZmZlY3QgfCB1bmRlZmluZWR9IEZpcnN0IGRldGVybWluaXN0aWMgZXhjbHVzaW9uLlxuICovXG5mdW5jdGlvbiBibG9ja0V4Y2x1ZGVkKGJsb2NrKSB7XG4gIGlmICghYmxvY2sgfHwgdHlwZW9mIGJsb2NrICE9IFwib2JqZWN0XCIgfHwgIUFycmF5LmlzQXJyYXkoYmxvY2suc3RhdGVtZW50cykpIHJldHVybiB1bmRlZmluZWRcbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgIGlmICghc3RhdGVtZW50IHx8IHR5cGVvZiBzdGF0ZW1lbnQgIT0gXCJvYmplY3RcIikgY29udGludWVcbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiICYmIGNvbnRhaW5zRWZmZWN0KHN0YXRlbWVudC5jb25kaXRpb24pKSB7XG4gICAgICByZXR1cm4ge2RldGFpbDogXCJlZmZlY3RmdWwgY29uZGl0aW9uLWNvbnRyb2xsZWQgbG9vcCBjb25kaXRpb25cIiwgbG9jYXRpb246IHN0YXRlbWVudC5jb25kaXRpb24ubG9jYXRpb259XG4gICAgfVxuICAgIGNvbnN0IGV4cHJlc3Npb25zID0gc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBbc3RhdGVtZW50LmluaXRpYWxpemVyXSA6XG4gICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmV4cHJlc3Npb25dIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5leHByZXNzaW9uID8gW3N0YXRlbWVudC5leHByZXNzaW9uXSA6IFtdIDpcbiAgICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmNvbmRpdGlvbl0gOiBzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiA/IFtzdGF0ZW1lbnQubGlzdF0gOlxuICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIgPyBbc3RhdGVtZW50Lm1hcF0gOiBzdGF0ZW1lbnQua2luZCA9PSBcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmV4cHJlc3Npb25dIDpcbiAgICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJSYWlzZVN0YXRlbWVudFwiID8gW3N0YXRlbWVudC5lcnJvci5tZXNzYWdlXSA6IFtdXG4gICAgZm9yIChjb25zdCBleHByZXNzaW9uIG9mIGV4cHJlc3Npb25zKSB7XG4gICAgICBjb25zdCBjb25kaXRpb25hbCA9IGZpbmRDb25kaXRpb25hbEVmZmVjdChleHByZXNzaW9uKVxuICAgICAgaWYgKGNvbmRpdGlvbmFsKSByZXR1cm4ge2RldGFpbDogXCJlZmZlY3RmdWwgc2hvcnQtY2lyY3VpdCBCb29sZWFuQW5kL0Jvb2xlYW5PciBleHByZXNzaW9uXCIsIGxvY2F0aW9uOiBjb25kaXRpb25hbC5sb2NhdGlvbn1cbiAgICB9XG4gICAgY29uc3QgbmVzdGVkID0gc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiID8gW3N0YXRlbWVudC5jb25zZXF1ZW50LCAuLi4oc3RhdGVtZW50LmFsdGVybmF0ZSA/IFtzdGF0ZW1lbnQuYWx0ZXJuYXRlXSA6IFtdKV0gOlxuICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiID8gW3N0YXRlbWVudC5ib2R5XSA6XG4gICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiVHJ5U3RhdGVtZW50XCIgPyBbc3RhdGVtZW50LmJvZHksIHN0YXRlbWVudC5jYXRjaEJvZHldIDogW11cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5lc3RlZCkge1xuICAgICAgY29uc3QgZm91bmQgPSBibG9ja0V4Y2x1ZGVkKGNoaWxkKVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEZpbmRzIGFuIGVmZmVjdCBiZWxvdyBhIHNob3J0LWNpcmN1aXQgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBFeHByZXNzaW9uIHJvb3QuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbiB8IHVuZGVmaW5lZH0gSW52YWxpZCBjb25kaXRpb25hbCBlZmZlY3QuXG4gKi9cbmZ1bmN0aW9uIGZpbmRDb25kaXRpb25hbEVmZmVjdChleHByZXNzaW9uKSB7XG4gIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiKSByZXR1cm4gdW5kZWZpbmVkXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIgJiYgW1wiQm9vbGVhbkFuZFwiLCBcIkJvb2xlYW5PclwiXS5pbmNsdWRlcyhleHByZXNzaW9uLm9wZXJhdGlvbikgJiZcbiAgICAoY29udGFpbnNFZmZlY3QoZXhwcmVzc2lvbi5sZWZ0KSB8fCBjb250YWluc0VmZmVjdChleHByZXNzaW9uLnJpZ2h0KSkpIHJldHVybiBleHByZXNzaW9uXG4gIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4oZXhwcmVzc2lvbikpIHtcbiAgICBjb25zdCBmb3VuZCA9IGZpbmRDb25kaXRpb25hbEVmZmVjdChjaGlsZClcbiAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZFxuICB9XG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhbiBleHByZXNzaW9uIGV2YWx1YXRlcyBhbiBlZmZlY3QuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBFeHByZXNzaW9uIHJvb3QuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBhbiBlZmZlY3QgaXMgcmVhY2hhYmxlLlxuICovXG5mdW5jdGlvbiBjb250YWluc0VmZmVjdChleHByZXNzaW9uKSB7XG4gIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiKSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgfHwgQm9vbGVhbihSZWZsZWN0LmdldChleHByZXNzaW9uLCBcImVmZmVjdFNpdGVJZFwiKSkgfHwgY2hpbGRyZW4oZXhwcmVzc2lvbikuc29tZShjb250YWluc0VmZmVjdClcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGNoaWxkIGV4cHJlc3Npb25zIGluIGV2YWx1YXRpb24gb3JkZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBQYXJlbnQgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9uW119IENoaWxkcmVuLlxuICovXG5mdW5jdGlvbiBjaGlsZHJlbihleHByZXNzaW9uKSB7XG4gIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiKSByZXR1cm4gW11cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJSZWZlcmVuY2VDb25zdHJ1Y3Rpb25cIiB8fFxuICAgIGV4cHJlc3Npb24ua2luZCA9PSBcIlJlY29yZENvbnN0cnVjdGlvblwiKSByZXR1cm4gZXhwcmVzc2lvbi5hcmd1bWVudHNcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5yZWNlaXZlciwgLi4uZXhwcmVzc2lvbi5hcmd1bWVudHNdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5leHByZXNzaW9uXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24ubGVmdCwgZXhwcmVzc2lvbi5yaWdodF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24ub3BlcmFuZF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiKSByZXR1cm4gW2V4cHJlc3Npb24udmFsdWVdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbElzUHJlc2VudFwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsVW53cmFwXCIpIHJldHVybiBbZXhwcmVzc2lvbi5vcGVyYW5kXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdExpdGVyYWxcIikgcmV0dXJuIGV4cHJlc3Npb24uZWxlbWVudHNcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExpdGVyYWxcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcmRlcmVkTWFwTGl0ZXJhbFwiKSByZXR1cm4gZXhwcmVzc2lvbi5lbnRyaWVzLmZsYXRNYXAoKHtrZXksIHZhbHVlfSkgPT4gW2tleSwgdmFsdWVdKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdEluZGV4RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24uY29sbGVjdGlvbiwgZXhwcmVzc2lvbi5pbmRleF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLmNvbGxlY3Rpb24sIGV4cHJlc3Npb24ua2V5XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5jb2xsZWN0aW9uXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSByZXR1cm4gW2V4cHJlc3Npb24ucmVjZWl2ZXJdXG4gIHJldHVybiBbXVxufVxuXG5jb25zdCBwaHBTdXBwb3J0ID0gYC8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydCAqL1xuZmluYWwgY2xhc3MgUHJvYmVPcGVyYXRpb25GYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7fVxuZmluYWwgY2xhc3MgUHJvYmVBY3F1aXJlRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24ge31cbmZpbmFsIGNsYXNzIFByb2JlUmVhZEZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHt9XG5maW5hbCBjbGFzcyBQcm9iZUNsb3NlRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24ge31cbmZpbmFsIGNsYXNzIFByb2JlUmVzb3VyY2VDbG9zZWQgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHt9XG5maW5hbCBjbGFzcyBQcm9iZVJlc291cmNlIHtcbiAgICBwdWJsaWMgYm9vbCAkY2xvc2VkID0gZmFsc2U7XG4gICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KHB1YmxpYyBtaXhlZCAkaGFuZGxlKSB7fVxufVxuJEdMT0JBTFNbJ19fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSddID0gW107XG5mdW5jdGlvbiBwcm9iZUVmZmVjdChzdHJpbmcgJGxhYmVsLCBpbnQgJHZhbHVlLCBib29sICRmYWlsKTogaW50IHtcbiAgICAkR0xPQkFMU1snX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlJ11bXSA9ICdlZmZlY3Q6JyAuICRsYWJlbDtcbiAgICBpZiAoJGZhaWwpIHRocm93IG5ldyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUoJ1Byb2JlT3BlcmF0aW9uRmFpbHVyZScpO1xuICAgIHJldHVybiAkdmFsdWU7XG59XG5mdW5jdGlvbiBwcm9iZUFjcXVpcmUoYm9vbCAkZmFpbCk6IFByb2JlUmVzb3VyY2Uge1xuICAgICRHTE9CQUxTWydfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2UnXVtdID0gJ2FjcXVpcmUnO1xuICAgIGlmICgkZmFpbCkgdGhyb3cgbmV3IFByb2JlQWNxdWlyZUZhaWx1cmUoJ1Byb2JlQWNxdWlyZUZhaWx1cmUnKTtcbiAgICB0cnkgeyAkaGFuZGxlID0gQGZvcGVuKChzdHJpbmcpIGdldGVudignU0VNQU5USUZPTERfVEFTSzAzNF9QUk9CRV9QQVRIJyksICdyYicpOyB9XG4gICAgY2F0Y2ggKFRocm93YWJsZSkgeyB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZSgnUHJvYmVBY3F1aXJlRmFpbHVyZScpOyB9XG4gICAgaWYgKCRoYW5kbGUgPT09IGZhbHNlKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZSgnUHJvYmVBY3F1aXJlRmFpbHVyZScpO1xuICAgIHJldHVybiBuZXcgUHJvYmVSZXNvdXJjZSgkaGFuZGxlKTtcbn1cbmZ1bmN0aW9uIHByb2JlUmVhZChQcm9iZVJlc291cmNlICRyZXNvdXJjZSwgYm9vbCAkZmFpbCk6ID9zdHJpbmcge1xuICAgIGlmICgkcmVzb3VyY2UtPmNsb3NlZCkgdGhyb3cgbmV3IFByb2JlUmVzb3VyY2VDbG9zZWQoJ1Byb2JlUmVzb3VyY2VDbG9zZWQnKTtcbiAgICAkR0xPQkFMU1snX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlJ11bXSA9ICdyZWFkJztcbiAgICBpZiAoJGZhaWwpIHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKCdQcm9iZVJlYWRGYWlsdXJlJyk7XG4gICAgdHJ5IHsgJGxpbmUgPSBAZmdldHMoJHJlc291cmNlLT5oYW5kbGUpOyB9XG4gICAgY2F0Y2ggKFRocm93YWJsZSkgeyB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZSgnUHJvYmVSZWFkRmFpbHVyZScpOyB9XG4gICAgaWYgKCRsaW5lID09PSBmYWxzZSkge1xuICAgICAgICBpZiAoZmVvZigkcmVzb3VyY2UtPmhhbmRsZSkpIHJldHVybiBudWxsO1xuICAgICAgICB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZSgnUHJvYmVSZWFkRmFpbHVyZScpO1xuICAgIH1cbiAgICByZXR1cm4gcnRyaW0oJGxpbmUsIFwiXFxcXHJcXFxcblwiKTtcbn1cbmZ1bmN0aW9uIHByb2JlQ2xvc2UoUHJvYmVSZXNvdXJjZSAkcmVzb3VyY2UsIGJvb2wgJGZhaWwpOiB2b2lkIHtcbiAgICBpZiAoJHJlc291cmNlLT5jbG9zZWQpIHRocm93IG5ldyBQcm9iZVJlc291cmNlQ2xvc2VkKCdQcm9iZVJlc291cmNlQ2xvc2VkJyk7XG4gICAgJEdMT0JBTFNbJ19fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSddW10gPSAnY2xvc2UnO1xuICAgIHRyeSB7ICRjbG9zZWQgPSBAZmNsb3NlKCRyZXNvdXJjZS0+aGFuZGxlKTsgfVxuICAgIGNhdGNoIChUaHJvd2FibGUpIHsgJHJlc291cmNlLT5jbG9zZWQgPSB0cnVlOyB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoJ1Byb2JlQ2xvc2VGYWlsdXJlJyk7IH1cbiAgICAkcmVzb3VyY2UtPmNsb3NlZCA9IHRydWU7XG4gICAgaWYgKCRmYWlsIHx8ICEkY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoJ1Byb2JlQ2xvc2VGYWlsdXJlJyk7XG59XG5mdW5jdGlvbiBwcm9iZVRyYWNlKCk6IHN0cmluZyB7IHJldHVybiBpbXBsb2RlKCcsJywgJEdMT0JBTFNbJ19fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSddKTsgfVxuLyogc2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0LWVuZCAqL1xuXG5gXG5cbmNvbnN0IHJ1YnlTdXBwb3J0ID0gYCMgc2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0XG5jbGFzcyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUgPCBTdGFuZGFyZEVycm9yOyBlbmRcbmNsYXNzIFByb2JlQWNxdWlyZUZhaWx1cmUgPCBTdGFuZGFyZEVycm9yOyBlbmRcbmNsYXNzIFByb2JlUmVhZEZhaWx1cmUgPCBTdGFuZGFyZEVycm9yOyBlbmRcbmNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIDwgU3RhbmRhcmRFcnJvcjsgZW5kXG5jbGFzcyBQcm9iZVJlc291cmNlQ2xvc2VkIDwgU3RhbmRhcmRFcnJvcjsgZW5kXG5jbGFzcyBQcm9iZVJlc291cmNlXG4gIGF0dHJfYWNjZXNzb3IgOmhhbmRsZSwgOmNsb3NlZFxuICBkZWYgaW5pdGlhbGl6ZShoYW5kbGUpOyBAaGFuZGxlID0gaGFuZGxlOyBAY2xvc2VkID0gZmFsc2U7IGVuZFxuZW5kXG4kX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlID0gW11cbmRlZiBwcm9iZUVmZmVjdChsYWJlbCwgdmFsdWUsIGZhaWxfdmFsdWUpXG4gICRfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2UgPDwgXCJlZmZlY3Q6I3tsYWJlbH1cIlxuICByYWlzZSBQcm9iZU9wZXJhdGlvbkZhaWx1cmUsIFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIgaWYgZmFpbF92YWx1ZVxuICB2YWx1ZVxuZW5kXG5kZWYgcHJvYmVBY3F1aXJlKGZhaWxfdmFsdWUpXG4gICRfX3NlbWFudGlmb2xkX3Rhc2swMzRfdHJhY2UgPDwgXCJhY3F1aXJlXCJcbiAgcmFpc2UgUHJvYmVBY3F1aXJlRmFpbHVyZSwgXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCIgaWYgZmFpbF92YWx1ZVxuICBiZWdpbjsgUHJvYmVSZXNvdXJjZS5uZXcoRmlsZS5vcGVuKEVOVi5mZXRjaChcIlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSFwiKSwgXCJyXCIpKTsgcmVzY3VlIFByb2JlQWNxdWlyZUZhaWx1cmU7IHJhaXNlOyByZXNjdWUgU3RhbmRhcmRFcnJvcjsgcmFpc2UgUHJvYmVBY3F1aXJlRmFpbHVyZSwgXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCI7IGVuZFxuZW5kXG5kZWYgcHJvYmVSZWFkKHJlc291cmNlLCBmYWlsX3ZhbHVlKVxuICByYWlzZSBQcm9iZVJlc291cmNlQ2xvc2VkLCBcIlByb2JlUmVzb3VyY2VDbG9zZWRcIiBpZiByZXNvdXJjZS5jbG9zZWRcbiAgJF9fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZSA8PCBcInJlYWRcIlxuICByYWlzZSBQcm9iZVJlYWRGYWlsdXJlLCBcIlByb2JlUmVhZEZhaWx1cmVcIiBpZiBmYWlsX3ZhbHVlXG4gIGJlZ2luOyB2YWx1ZSA9IHJlc291cmNlLmhhbmRsZS5nZXRzOyB2YWx1ZS5uaWw/ID8gbmlsIDogdmFsdWUuY2hvbXA7IHJlc2N1ZSBQcm9iZVJlYWRGYWlsdXJlOyByYWlzZTsgcmVzY3VlIFN0YW5kYXJkRXJyb3I7IHJhaXNlIFByb2JlUmVhZEZhaWx1cmUsIFwiUHJvYmVSZWFkRmFpbHVyZVwiOyBlbmRcbmVuZFxuZGVmIHByb2JlQ2xvc2UocmVzb3VyY2UsIGZhaWxfdmFsdWUpXG4gIHJhaXNlIFByb2JlUmVzb3VyY2VDbG9zZWQsIFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiIGlmIHJlc291cmNlLmNsb3NlZFxuICAkX19zZW1hbnRpZm9sZF90YXNrMDM0X3RyYWNlIDw8IFwiY2xvc2VcIlxuICBiZWdpbjsgcmVzb3VyY2UuaGFuZGxlLmNsb3NlOyByZXNjdWUgU3RhbmRhcmRFcnJvcjsgcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgcmFpc2UgUHJvYmVDbG9zZUZhaWx1cmUsIFwiUHJvYmVDbG9zZUZhaWx1cmVcIjsgZW5kXG4gIHJlc291cmNlLmNsb3NlZCA9IHRydWVcbiAgcmFpc2UgUHJvYmVDbG9zZUZhaWx1cmUsIFwiUHJvYmVDbG9zZUZhaWx1cmVcIiBpZiBmYWlsX3ZhbHVlXG4gIG5pbFxuZW5kXG5kZWYgcHJvYmVUcmFjZTsgJF9fc2VtYW50aWZvbGRfdGFzazAzNF90cmFjZS5qb2luKFwiLFwiKTsgZW5kXG4jIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydC1lbmRcblxuYFxuXG5jb25zdCBqYXZhc2NyaXB0U3VwcG9ydCA9IGAvKiBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQgKi9cbmNvbnN0IF9fc2VtYW50aWZvbGRUYXNrMDM0RnMgPSBwcm9jZXNzLmdldEJ1aWx0aW5Nb2R1bGUoXCJub2RlOmZzXCIpXG5jbGFzcyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVBY3F1aXJlRmFpbHVyZSBleHRlbmRzIEVycm9yIHt9XG5jbGFzcyBQcm9iZVJlYWRGYWlsdXJlIGV4dGVuZHMgRXJyb3Ige31cbmNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIGV4dGVuZHMgRXJyb3Ige31cbmNsYXNzIFByb2JlUmVzb3VyY2VDbG9zZWQgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVSZXNvdXJjZSB7IGNvbnN0cnVjdG9yKGhhbmRsZSkgeyB0aGlzLmhhbmRsZSA9IGhhbmRsZTsgdGhpcy5jbG9zZWQgPSBmYWxzZTsgdGhpcy5wb3NpdGlvbiA9IDAgfSB9XG5jb25zdCBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlID0gW11cbmZ1bmN0aW9uIHByb2JlRWZmZWN0KGxhYmVsLCB2YWx1ZSwgZmFpbCkgeyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLnB1c2goXFxgZWZmZWN0OlxcJHtsYWJlbH1cXGApOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlT3BlcmF0aW9uRmFpbHVyZShcIlByb2JlT3BlcmF0aW9uRmFpbHVyZVwiKTsgcmV0dXJuIHZhbHVlIH1cbmZ1bmN0aW9uIHByb2JlQWNxdWlyZShmYWlsKSB7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcImFjcXVpcmVcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZShcIlByb2JlQWNxdWlyZUZhaWx1cmVcIik7IHRyeSB7IHJldHVybiBuZXcgUHJvYmVSZXNvdXJjZShfX3NlbWFudGlmb2xkVGFzazAzNEZzLm9wZW5TeW5jKHByb2Nlc3MuZW52LlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSCwgXCJyXCIpKSB9IGNhdGNoIHsgdGhyb3cgbmV3IFByb2JlQWNxdWlyZUZhaWx1cmUoXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCIpIH0gfVxuZnVuY3Rpb24gcHJvYmVSZWFkKHJlc291cmNlLCBmYWlsKSB7IGlmIChyZXNvdXJjZS5jbG9zZWQpIHRocm93IG5ldyBQcm9iZVJlc291cmNlQ2xvc2VkKFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiKTsgX19zZW1hbnRpZm9sZFRhc2swMzRUcmFjZS5wdXNoKFwicmVhZFwiKTsgaWYgKGZhaWwpIHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKFwiUHJvYmVSZWFkRmFpbHVyZVwiKTsgdHJ5IHsgY29uc3QgYnl0ZXMgPSBbXTsgY29uc3QgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDEpOyB3aGlsZSAodHJ1ZSkgeyBjb25zdCBjb3VudCA9IF9fc2VtYW50aWZvbGRUYXNrMDM0RnMucmVhZFN5bmMocmVzb3VyY2UuaGFuZGxlLCBidWZmZXIsIDAsIDEsIHJlc291cmNlLnBvc2l0aW9uKyspOyBpZiAoY291bnQgPT09IDApIHJldHVybiBieXRlcy5sZW5ndGggPT09IDAgPyBudWxsIDogQnVmZmVyLmZyb20oYnl0ZXMpLnRvU3RyaW5nKFwidXRmOFwiKTsgaWYgKGJ1ZmZlclswXSA9PT0gMTApIHJldHVybiBCdWZmZXIuZnJvbShieXRlcykudG9TdHJpbmcoXCJ1dGY4XCIpLnJlcGxhY2UoL1xcXFxyJC91LCBcIlwiKTsgYnl0ZXMucHVzaChidWZmZXJbMF0pIH0gfSBjYXRjaCB7IHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKFwiUHJvYmVSZWFkRmFpbHVyZVwiKSB9IH1cbmZ1bmN0aW9uIHByb2JlQ2xvc2UocmVzb3VyY2UsIGZhaWwpIHsgaWYgKHJlc291cmNlLmNsb3NlZCkgdGhyb3cgbmV3IFByb2JlUmVzb3VyY2VDbG9zZWQoXCJQcm9iZVJlc291cmNlQ2xvc2VkXCIpOyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLnB1c2goXCJjbG9zZVwiKTsgdHJ5IHsgX19zZW1hbnRpZm9sZFRhc2swMzRGcy5jbG9zZVN5bmMocmVzb3VyY2UuaGFuZGxlKSB9IGNhdGNoIHsgcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgdGhyb3cgbmV3IFByb2JlQ2xvc2VGYWlsdXJlKFwiUHJvYmVDbG9zZUZhaWx1cmVcIikgfSByZXNvdXJjZS5jbG9zZWQgPSB0cnVlOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlQ2xvc2VGYWlsdXJlKFwiUHJvYmVDbG9zZUZhaWx1cmVcIikgfVxuZnVuY3Rpb24gcHJvYmVUcmFjZSgpIHsgcmV0dXJuIF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2Uuam9pbihcIixcIikgfVxuLyogc2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0LWVuZCAqL1xuXG5gXG5cbmNvbnN0IHR5cGVzY3JpcHRTdXBwb3J0ID0gYC8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydCAqL1xuY29uc3QgX19zZW1hbnRpZm9sZFRhc2swMzRGcyA9IHByb2Nlc3MuZ2V0QnVpbHRpbk1vZHVsZShcIm5vZGU6ZnNcIilcbmNsYXNzIFByb2JlT3BlcmF0aW9uRmFpbHVyZSBleHRlbmRzIEVycm9yIHt9XG5jbGFzcyBQcm9iZUFjcXVpcmVGYWlsdXJlIGV4dGVuZHMgRXJyb3Ige31cbmNsYXNzIFByb2JlUmVhZEZhaWx1cmUgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVDbG9zZUZhaWx1cmUgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgUHJvYmVSZXNvdXJjZUNsb3NlZCBleHRlbmRzIEVycm9yIHt9XG5jbGFzcyBQcm9iZVJlc291cmNlIHsgY2xvc2VkID0gZmFsc2U7IHBvc2l0aW9uID0gMDsgY29uc3RydWN0b3IocmVhZG9ubHkgaGFuZGxlOiBudW1iZXIpIHt9IH1cbmNvbnN0IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2U6IHN0cmluZ1tdID0gW11cbmZ1bmN0aW9uIHByb2JlRWZmZWN0KGxhYmVsOiBzdHJpbmcsIHZhbHVlOiBudW1iZXIsIGZhaWw6IGJvb2xlYW4pOiBudW1iZXIgeyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLnB1c2goXFxgZWZmZWN0OlxcJHtsYWJlbH1cXGApOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlT3BlcmF0aW9uRmFpbHVyZShcIlByb2JlT3BlcmF0aW9uRmFpbHVyZVwiKTsgcmV0dXJuIHZhbHVlIH1cbmZ1bmN0aW9uIHByb2JlQWNxdWlyZShmYWlsOiBib29sZWFuKTogUHJvYmVSZXNvdXJjZSB7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcImFjcXVpcmVcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZShcIlByb2JlQWNxdWlyZUZhaWx1cmVcIik7IHRyeSB7IHJldHVybiBuZXcgUHJvYmVSZXNvdXJjZShfX3NlbWFudGlmb2xkVGFzazAzNEZzLm9wZW5TeW5jKHByb2Nlc3MuZW52LlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSCBhcyBzdHJpbmcsIFwiclwiKSkgfSBjYXRjaCB7IHRocm93IG5ldyBQcm9iZUFjcXVpcmVGYWlsdXJlKFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiKSB9IH1cbmZ1bmN0aW9uIHByb2JlUmVhZChyZXNvdXJjZTogUHJvYmVSZXNvdXJjZSwgZmFpbDogYm9vbGVhbik6IHN0cmluZyB8IG51bGwgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZChcIlByb2JlUmVzb3VyY2VDbG9zZWRcIik7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcInJlYWRcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZShcIlByb2JlUmVhZEZhaWx1cmVcIik7IHRyeSB7IGNvbnN0IGJ5dGVzOiBudW1iZXJbXSA9IFtdOyBjb25zdCBidWZmZXIgPSBCdWZmZXIuYWxsb2MoMSk7IHdoaWxlICh0cnVlKSB7IGNvbnN0IGNvdW50ID0gX19zZW1hbnRpZm9sZFRhc2swMzRGcy5yZWFkU3luYyhyZXNvdXJjZS5oYW5kbGUsIGJ1ZmZlciwgMCwgMSwgcmVzb3VyY2UucG9zaXRpb24rKyk7IGlmIChjb3VudCA9PT0gMCkgcmV0dXJuIGJ5dGVzLmxlbmd0aCA9PT0gMCA/IG51bGwgOiBCdWZmZXIuZnJvbShieXRlcykudG9TdHJpbmcoXCJ1dGY4XCIpOyBpZiAoYnVmZmVyWzBdID09PSAxMCkgcmV0dXJuIEJ1ZmZlci5mcm9tKGJ5dGVzKS50b1N0cmluZyhcInV0ZjhcIikucmVwbGFjZSgvXFxcXHIkL3UsIFwiXCIpOyBieXRlcy5wdXNoKGJ1ZmZlclswXSkgfSB9IGNhdGNoIHsgdGhyb3cgbmV3IFByb2JlUmVhZEZhaWx1cmUoXCJQcm9iZVJlYWRGYWlsdXJlXCIpIH0gfVxuZnVuY3Rpb24gcHJvYmVDbG9zZShyZXNvdXJjZTogUHJvYmVSZXNvdXJjZSwgZmFpbDogYm9vbGVhbik6IHZvaWQgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZChcIlByb2JlUmVzb3VyY2VDbG9zZWRcIik7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UucHVzaChcImNsb3NlXCIpOyB0cnkgeyBfX3NlbWFudGlmb2xkVGFzazAzNEZzLmNsb3NlU3luYyhyZXNvdXJjZS5oYW5kbGUpIH0gY2F0Y2ggeyByZXNvdXJjZS5jbG9zZWQgPSB0cnVlOyB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoXCJQcm9iZUNsb3NlRmFpbHVyZVwiKSB9IHJlc291cmNlLmNsb3NlZCA9IHRydWU7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVDbG9zZUZhaWx1cmUoXCJQcm9iZUNsb3NlRmFpbHVyZVwiKSB9XG5mdW5jdGlvbiBwcm9iZVRyYWNlKCk6IHN0cmluZyB7IHJldHVybiBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmpvaW4oXCIsXCIpIH1cbi8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydC1lbmQgKi9cblxuYFxuXG5jb25zdCBqYXZhVG9wU3VwcG9ydCA9IGAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnRcbmZpbmFsIGNsYXNzIFByb2JlT3BlcmF0aW9uRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUoKSB7IHN1cGVyKFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlQWNxdWlyZUZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsgUHJvYmVBY3F1aXJlRmFpbHVyZSgpIHsgc3VwZXIoXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlUmVhZEZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsgUHJvYmVSZWFkRmFpbHVyZSgpIHsgc3VwZXIoXCJQcm9iZVJlYWRGYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlQ2xvc2VGYWlsdXJlKCkgeyBzdXBlcihcIlByb2JlQ2xvc2VGYWlsdXJlXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlUmVzb3VyY2VDbG9zZWQgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsgUHJvYmVSZXNvdXJjZUNsb3NlZCgpIHsgc3VwZXIoXCJQcm9iZVJlc291cmNlQ2xvc2VkXCIpOyB9IH1cbmZpbmFsIGNsYXNzIFByb2JlUmVzb3VyY2UgeyBmaW5hbCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbCBoYW5kbGU7IGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7IFByb2JlUmVzb3VyY2UoamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwgaGFuZGxlKSB7IHRoaXMuaGFuZGxlID0gaGFuZGxlOyB9IH1cbi8vIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydC10b3AtZW5kXG5cbmBcblxuY29uc3QgamF2YU1lbWJlclN1cHBvcnQgPSBgICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtbWVtYmVyc1xuICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuQXJyYXlMaXN0PFN0cmluZz4gX19zZW1hbnRpZm9sZFRhc2swMzRUcmFjZSA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PD4oKTtcbiAgc3RhdGljIGludCBwcm9iZUVmZmVjdChTdHJpbmcgbGFiZWwsIGludCB2YWx1ZSwgYm9vbGVhbiBmYWlsKSB7IF9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2UuYWRkKFwiZWZmZWN0OlwiICsgbGFiZWwpOyBpZiAoZmFpbCkgdGhyb3cgbmV3IFByb2JlT3BlcmF0aW9uRmFpbHVyZSgpOyByZXR1cm4gdmFsdWU7IH1cbiAgc3RhdGljIFByb2JlUmVzb3VyY2UgcHJvYmVBY3F1aXJlKGJvb2xlYW4gZmFpbCkgeyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmFkZChcImFjcXVpcmVcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVBY3F1aXJlRmFpbHVyZSgpOyB0cnkgeyByZXR1cm4gbmV3IFByb2JlUmVzb3VyY2UoamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWwub3BlbihqYXZhLm5pby5maWxlLlBhdGgub2YoU3lzdGVtLmdldGVudihcIlNFTUFOVElGT0xEX1RBU0swMzRfUFJPQkVfUEFUSFwiKSkpKTsgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IGphdmEuaW8uSU9FeGNlcHRpb24gZXhjZXB0aW9uKSB7IHRocm93IG5ldyBQcm9iZUFjcXVpcmVGYWlsdXJlKCk7IH0gfVxuICBzdGF0aWMgamF2YS51dGlsLk9wdGlvbmFsPFN0cmluZz4gcHJvYmVSZWFkKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZCgpOyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmFkZChcInJlYWRcIik7IGlmIChmYWlsKSB0aHJvdyBuZXcgUHJvYmVSZWFkRmFpbHVyZSgpOyB0cnkgeyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOyBqYXZhLm5pby5CeXRlQnVmZmVyIGJ1ZmZlciA9IGphdmEubmlvLkJ5dGVCdWZmZXIuYWxsb2NhdGUoMSk7IHdoaWxlICh0cnVlKSB7IGJ1ZmZlci5jbGVhcigpOyBpbnQgY291bnQgPSByZXNvdXJjZS5oYW5kbGUucmVhZChidWZmZXIpOyBpZiAoY291bnQgPCAwKSByZXR1cm4gYnl0ZXMuc2l6ZSgpID09IDAgPyBqYXZhLnV0aWwuT3B0aW9uYWwuZW1wdHkoKSA6IGphdmEudXRpbC5PcHRpb25hbC5vZihieXRlcy50b1N0cmluZyhqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKTsgYnVmZmVyLmZsaXAoKTsgYnl0ZSB2YWx1ZSA9IGJ1ZmZlci5nZXQoKTsgaWYgKHZhbHVlID09IDEwKSByZXR1cm4gamF2YS51dGlsLk9wdGlvbmFsLm9mKGJ5dGVzLnRvU3RyaW5nKGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkucmVwbGFjZUZpcnN0KFwiXFxcXHIkXCIsIFwiXCIpKTsgYnl0ZXMud3JpdGUodmFsdWUpOyB9IH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZXhjZXB0aW9uKSB7IHRocm93IG5ldyBQcm9iZVJlYWRGYWlsdXJlKCk7IH0gfVxuICBzdGF0aWMgdm9pZCBwcm9iZUNsb3NlKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyBpZiAocmVzb3VyY2UuY2xvc2VkKSB0aHJvdyBuZXcgUHJvYmVSZXNvdXJjZUNsb3NlZCgpOyBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlLmFkZChcImNsb3NlXCIpOyB0cnkgeyByZXNvdXJjZS5oYW5kbGUuY2xvc2UoKTsgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBleGNlcHRpb24pIHsgcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgdGhyb3cgbmV3IFByb2JlQ2xvc2VGYWlsdXJlKCk7IH0gcmVzb3VyY2UuY2xvc2VkID0gdHJ1ZTsgaWYgKGZhaWwpIHRocm93IG5ldyBQcm9iZUNsb3NlRmFpbHVyZSgpOyB9XG4gIHN0YXRpYyBTdHJpbmcgcHJvYmVUcmFjZSgpIHsgcmV0dXJuIFN0cmluZy5qb2luKFwiLFwiLCBfX3NlbWFudGlmb2xkVGFzazAzNFRyYWNlKTsgfVxuICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtbWVtYmVycy1lbmRcblxuYFxuXG5jb25zdCBqYXZhUHJvZ3JhbU5lc3RlZFN1cHBvcnQgPSBgICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtcHJvZ3JhbVxuICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb2JlT3BlcmF0aW9uRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geyBQcm9iZU9wZXJhdGlvbkZhaWx1cmUoKSB7IHN1cGVyKFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCIpOyB9IH1cbiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm9iZUFjcXVpcmVGYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlQWNxdWlyZUZhaWx1cmUoKSB7IHN1cGVyKFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiKTsgfSB9XG4gIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvYmVSZWFkRmFpbHVyZSBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24geyBQcm9iZVJlYWRGYWlsdXJlKCkgeyBzdXBlcihcIlByb2JlUmVhZEZhaWx1cmVcIik7IH0gfVxuICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb2JlQ2xvc2VGYWlsdXJlIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlQ2xvc2VGYWlsdXJlKCkgeyBzdXBlcihcIlByb2JlQ2xvc2VGYWlsdXJlXCIpOyB9IH1cbiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm9iZVJlc291cmNlQ2xvc2VkIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7IFByb2JlUmVzb3VyY2VDbG9zZWQoKSB7IHN1cGVyKFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiKTsgfSB9XG4gIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvYmVSZXNvdXJjZSB7IGZpbmFsIGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsIGhhbmRsZTsgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsgUHJvYmVSZXNvdXJjZShqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbCBoYW5kbGUpIHsgdGhpcy5oYW5kbGUgPSBoYW5kbGU7IH0gfVxuICAvLyBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtcHJvZ3JhbS1lbmRcblxuYFxuXG4vKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZz59ICovXG5jb25zdCBqYXZhUHJvdmlkZXJTaGltcyA9IHtcbiAgcHJvYmVBY3F1aXJlOiBcInB1YmxpYyBzdGF0aWMgUHJvYmVSZXNvdXJjZSBfX3NlbWFudGlmb2xkX3Byb3ZpZGVyX2phdmFfcHJvYmVBY3F1aXJlKGJvb2xlYW4gZmFpbCkgeyByZXR1cm4gcHJvYmVBY3F1aXJlKGZhaWwpOyB9XCIsXG4gIHByb2JlQ2xvc2U6IFwicHVibGljIHN0YXRpYyB2b2lkIF9fc2VtYW50aWZvbGRfcHJvdmlkZXJfamF2YV9wcm9iZUNsb3NlKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyBwcm9iZUNsb3NlKHJlc291cmNlLCBmYWlsKTsgfVwiLFxuICBwcm9iZUVmZmVjdDogXCJwdWJsaWMgc3RhdGljIGludCBfX3NlbWFudGlmb2xkX3Byb3ZpZGVyX2phdmFfcHJvYmVFZmZlY3QoU3RyaW5nIGxhYmVsLCBpbnQgdmFsdWUsIGJvb2xlYW4gZmFpbCkgeyByZXR1cm4gcHJvYmVFZmZlY3QobGFiZWwsIHZhbHVlLCBmYWlsKTsgfVwiLFxuICBwcm9iZVJlYWQ6IFwicHVibGljIHN0YXRpYyBqYXZhLnV0aWwuT3B0aW9uYWw8U3RyaW5nPiBfX3NlbWFudGlmb2xkX3Byb3ZpZGVyX2phdmFfcHJvYmVSZWFkKFByb2JlUmVzb3VyY2UgcmVzb3VyY2UsIGJvb2xlYW4gZmFpbCkgeyByZXR1cm4gcHJvYmVSZWFkKHJlc291cmNlLCBmYWlsKTsgfVwiLFxuICBwcm9iZVRyYWNlOiBcInB1YmxpYyBzdGF0aWMgU3RyaW5nIF9fc2VtYW50aWZvbGRfcHJvdmlkZXJfamF2YV9wcm9iZVRyYWNlKCkgeyByZXR1cm4gcHJvYmVUcmFjZSgpOyB9XCJcbn1cbiJdfQ==
|